aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2014-11-25 21:00:58 +0000
committerEd Maste <emaste@FreeBSD.org>2014-11-25 21:00:58 +0000
commit0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (patch)
treec94307da318be46e5aeea1a325c1e91749506e4f /tools
parent03b99097822ca3ac69252d9afae716a584ed56c4 (diff)
downloadsrc-0cac4ca3916ac24ab6139d03cbfd18db9e715bfe.tar.gz
src-0cac4ca3916ac24ab6139d03cbfd18db9e715bfe.zip
Import LLDB as of upstream SVN r216948 (git 50f7fe44)vendor/lldb/lldb-r216948
This corresponds with the branchpoint for the 3.5 release. 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=275072 svn path=/vendor/lldb/lldb-r216948/; revision=275074; tag=vendor/lldb/lldb-r216948
Diffstat (limited to 'tools')
-rw-r--r--tools/driver/Driver.cpp242
-rw-r--r--tools/driver/Driver.h5
-rw-r--r--tools/driver/Platform.cpp25
-rw-r--r--tools/driver/Platform.h56
-rw-r--r--tools/lldb-mi/Driver.cpp1299
-rw-r--r--tools/lldb-mi/Driver.h163
-rw-r--r--tools/lldb-mi/MICmdArgContext.cpp255
-rw-r--r--tools/lldb-mi/MICmdArgContext.h61
-rw-r--r--tools/lldb-mi/MICmdArgSet.cpp420
-rw-r--r--tools/lldb-mi/MICmdArgSet.h109
-rw-r--r--tools/lldb-mi/MICmdArgValBase.cpp171
-rw-r--r--tools/lldb-mi/MICmdArgValBase.h157
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.cpp119
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.h63
-rw-r--r--tools/lldb-mi/MICmdArgValFile.cpp204
-rw-r--r--tools/lldb-mi/MICmdArgValFile.h61
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.cpp221
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.h103
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.cpp189
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.h98
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.cpp167
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.h65
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.cpp319
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.h109
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.cpp128
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.h65
-rw-r--r--tools/lldb-mi/MICmdArgValString.cpp502
-rw-r--r--tools/lldb-mi/MICmdArgValString.h76
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.cpp173
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.h66
-rw-r--r--tools/lldb-mi/MICmdBase.cpp263
-rw-r--r--tools/lldb-mi/MICmdBase.h156
-rw-r--r--tools/lldb-mi/MICmdCmd.cpp174
-rw-r--r--tools/lldb-mi/MICmdCmd.h104
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp1026
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.h292
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp1365
-rw-r--r--tools/lldb-mi/MICmdCmdData.h374
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.cpp143
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.h69
-rw-r--r--tools/lldb-mi/MICmdCmdExec.cpp982
-rw-r--r--tools/lldb-mi/MICmdCmdExec.h310
-rw-r--r--tools/lldb-mi/MICmdCmdFile.cpp184
-rw-r--r--tools/lldb-mi/MICmdCmdFile.h71
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.cpp232
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.h93
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.cpp260
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.h96
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.cpp100
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.h61
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.cpp588
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.h175
-rw-r--r--tools/lldb-mi/MICmdCmdStack.cpp634
-rw-r--r--tools/lldb-mi/MICmdCmdStack.h184
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.cpp129
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.h69
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.cpp102
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.h63
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.cpp217
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.h70
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp207
-rw-r--r--tools/lldb-mi/MICmdCmdThread.h76
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.cpp99
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.h61
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp1492
-rw-r--r--tools/lldb-mi/MICmdCmdVar.h382
-rw-r--r--tools/lldb-mi/MICmdCommands.cpp135
-rw-r--r--tools/lldb-mi/MICmdCommands.h36
-rw-r--r--tools/lldb-mi/MICmdData.cpp24
-rw-r--r--tools/lldb-mi/MICmdData.h74
-rw-r--r--tools/lldb-mi/MICmdFactory.cpp229
-rw-r--r--tools/lldb-mi/MICmdFactory.h99
-rw-r--r--tools/lldb-mi/MICmdInterpreter.cpp301
-rw-r--r--tools/lldb-mi/MICmdInterpreter.h78
-rw-r--r--tools/lldb-mi/MICmdInvoker.cpp333
-rw-r--r--tools/lldb-mi/MICmdInvoker.h118
-rw-r--r--tools/lldb-mi/MICmdMgr.cpp257
-rw-r--r--tools/lldb-mi/MICmdMgr.h83
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp110
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h88
-rw-r--r--tools/lldb-mi/MICmnBase.cpp144
-rw-r--r--tools/lldb-mi/MICmnBase.h60
-rw-r--r--tools/lldb-mi/MICmnConfig.h50
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.cpp89
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.h61
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp1312
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.h236
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp570
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h139
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp707
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.h125
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp1566
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h97
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.cpp153
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.h47
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.cpp324
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.h71
-rw-r--r--tools/lldb-mi/MICmnLog.cpp355
-rw-r--r--tools/lldb-mi/MICmnLog.h143
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.cpp420
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.h96
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.cpp161
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.h110
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.cpp142
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.h106
-rw-r--r--tools/lldb-mi/MICmnMIValue.cpp64
-rw-r--r--tools/lldb-mi/MICmnMIValue.h64
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.cpp98
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.h72
-rw-r--r--tools/lldb-mi/MICmnMIValueList.cpp203
-rw-r--r--tools/lldb-mi/MICmnMIValueList.h70
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.cpp141
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.h75
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.cpp227
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.h76
-rw-r--r--tools/lldb-mi/MICmnResources.cpp409
-rw-r--r--tools/lldb-mi/MICmnResources.h351
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.cpp257
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.h76
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.cpp421
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.h125
-rw-r--r--tools/lldb-mi/MICmnStreamStdinLinux.cpp212
-rw-r--r--tools/lldb-mi/MICmnStreamStdinLinux.h75
-rw-r--r--tools/lldb-mi/MICmnStreamStdinWindows.cpp279
-rw-r--r--tools/lldb-mi/MICmnStreamStdinWindows.h81
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.cpp230
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.h75
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.cpp167
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.h134
-rw-r--r--tools/lldb-mi/MIDataTypes.h100
-rw-r--r--tools/lldb-mi/MIDriver.cpp1276
-rw-r--r--tools/lldb-mi/MIDriver.h182
-rw-r--r--tools/lldb-mi/MIDriverBase.cpp195
-rw-r--r--tools/lldb-mi/MIDriverBase.h78
-rw-r--r--tools/lldb-mi/MIDriverMain.cpp393
-rw-r--r--tools/lldb-mi/MIDriverMgr.cpp762
-rw-r--r--tools/lldb-mi/MIDriverMgr.h138
-rw-r--r--tools/lldb-mi/MIReadMe.txt261
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.cpp84
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.h55
-rw-r--r--tools/lldb-mi/MIUtilDebug.cpp128
-rw-r--r--tools/lldb-mi/MIUtilDebug.h96
-rw-r--r--tools/lldb-mi/MIUtilFileStd.cpp290
-rw-r--r--tools/lldb-mi/MIUtilFileStd.h65
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.cpp124
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.h148
-rw-r--r--tools/lldb-mi/MIUtilSingletonBase.h71
-rw-r--r--tools/lldb-mi/MIUtilSingletonHelper.h95
-rw-r--r--tools/lldb-mi/MIUtilString.cpp680
-rw-r--r--tools/lldb-mi/MIUtilString.h85
-rw-r--r--tools/lldb-mi/MIUtilSystemLinux.cpp119
-rw-r--r--tools/lldb-mi/MIUtilSystemLinux.h57
-rw-r--r--tools/lldb-mi/MIUtilSystemOsx.cpp125
-rw-r--r--tools/lldb-mi/MIUtilSystemOsx.h57
-rw-r--r--tools/lldb-mi/MIUtilSystemWindows.cpp151
-rw-r--r--tools/lldb-mi/MIUtilSystemWindows.h56
-rw-r--r--tools/lldb-mi/MIUtilTermios.cpp69
-rw-r--r--tools/lldb-mi/MIUtilTermios.h30
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.cpp339
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.h170
-rw-r--r--tools/lldb-mi/MIUtilVariant.cpp392
-rw-r--r--tools/lldb-mi/MIUtilVariant.h288
-rw-r--r--tools/lldb-mi/Platform.cpp109
-rw-r--r--tools/lldb-mi/Platform.h109
-rw-r--r--tools/lldb-platform/lldb-platform.cpp7
165 files changed, 37063 insertions, 146 deletions
diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp
index 78d3a7e1c037..854310031c37 100644
--- a/tools/driver/Driver.cpp
+++ b/tools/driver/Driver.cpp
@@ -15,6 +15,14 @@
#include <limits.h>
#include <fcntl.h>
+// Includes for pipe()
+#if defined(_WIN32)
+#include <io.h>
+#include <fcntl.h>
+#else
+#include <unistd.h>
+#endif
+
#include <string>
#include <thread>
@@ -477,63 +485,19 @@ Driver::GetScriptLanguage() const
}
void
-Driver::ExecuteInitialCommands (bool before_file)
+Driver::WriteInitialCommands (bool before_file, SBStream &strm)
{
- size_t num_commands;
- std::vector<std::pair<bool, std::string> > *command_set;
- if (before_file)
- command_set = &(m_option_data.m_initial_commands);
- else
- command_set = &(m_option_data.m_after_file_commands);
+ std::vector<std::pair<bool, std::string> > &command_set = before_file ? m_option_data.m_initial_commands :
+ m_option_data.m_after_file_commands;
- num_commands = command_set->size();
- SBCommandReturnObject result;
- bool old_async = GetDebugger().GetAsync();
- GetDebugger().SetAsync(false);
- for (size_t idx = 0; idx < num_commands; idx++)
+ for (const auto &command_pair : command_set)
{
- bool is_file = (*command_set)[idx].first;
- const char *command = (*command_set)[idx].second.c_str();
- char command_string[PATH_MAX * 2];
- const bool dump_stream_only_if_no_immediate = true;
- const char *executed_command = command;
- if (is_file)
- {
- ::snprintf (command_string, sizeof(command_string), "command source -s %i '%s'", m_option_data.m_source_quietly, command);
- executed_command = command_string;
- }
-
- m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false);
- if (!m_option_data.m_source_quietly || result.Succeeded() == false)
- {
- const size_t output_size = result.GetOutputSize();
- if (output_size > 0)
- {
- const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate);
- if (cstr)
- printf ("%s", cstr);
- }
- const size_t error_size = result.GetErrorSize();
- if (error_size > 0)
- {
- const char *cstr = result.GetError(dump_stream_only_if_no_immediate);
- if (cstr)
- printf ("%s", cstr);
- }
- }
-
- if (result.Succeeded() == false)
- {
- const char *type = before_file ? "before file" : "after_file";
- if (is_file)
- ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command);
- else
- ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command);
- break;
- }
- result.Clear();
+ const char *command = command_pair.second.c_str();
+ if (command_pair.first)
+ strm.Printf("command source -s %i '%s'\n", m_option_data.m_source_quietly, command);
+ else
+ strm.Printf("%s\n", command);
}
- GetDebugger().SetAsync(old_async);
}
bool
@@ -857,8 +821,8 @@ Driver::MainLoop ()
m_debugger.SetErrorFileHandle (stderr, false);
m_debugger.SetOutputFileHandle (stdout, false);
- m_debugger.SetInputFileHandle (stdin, true);
-
+ m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
+
m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
struct winsize window_size;
@@ -882,77 +846,61 @@ Driver::MainLoop ()
}
// Now we handle options we got from the command line
- // First source in the commands specified to be run before the file arguments are processed.
- ExecuteInitialCommands(true);
-
- // Was there a core file specified?
- std::string core_file_spec("");
- if (!m_option_data.m_core_file.empty())
- core_file_spec.append("--core ").append(m_option_data.m_core_file);
+ SBStream commands_stream;
- char command_string[PATH_MAX * 2];
+ // First source in the commands specified to be run before the file arguments are processed.
+ WriteInitialCommands(true, commands_stream);
+
const size_t num_args = m_option_data.m_args.size();
if (num_args > 0)
{
char arch_name[64];
if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
- ::snprintf (command_string,
- sizeof (command_string),
- "target create --arch=%s %s \"%s\"",
- arch_name,
- core_file_spec.c_str(),
- m_option_data.m_args[0].c_str());
+ commands_stream.Printf("target create --arch=%s \"%s\"", arch_name, m_option_data.m_args[0].c_str());
else
- ::snprintf (command_string,
- sizeof(command_string),
- "target create %s \"%s\"",
- core_file_spec.c_str(),
- m_option_data.m_args[0].c_str());
-
- m_debugger.HandleCommand (command_string);
+ commands_stream.Printf("target create \"%s\"", m_option_data.m_args[0].c_str());
+
+ if (!m_option_data.m_core_file.empty())
+ {
+ commands_stream.Printf(" --core \"%s\"", m_option_data.m_core_file.c_str());
+ }
+ commands_stream.Printf("\n");
if (num_args > 1)
{
- m_debugger.HandleCommand ("settings clear target.run-args");
- char arg_cstr[1024];
+ commands_stream.Printf ("settings set -- target.run-args ");
for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
{
- ::snprintf (arg_cstr,
- sizeof(arg_cstr),
- "settings append target.run-args \"%s\"",
- m_option_data.m_args[arg_idx].c_str());
- m_debugger.HandleCommand (arg_cstr);
+ const char *arg_cstr = m_option_data.m_args[arg_idx].c_str();
+ if (strchr(arg_cstr, '"') == NULL)
+ commands_stream.Printf(" \"%s\"", arg_cstr);
+ else
+ commands_stream.Printf(" '%s'", arg_cstr);
}
+ commands_stream.Printf("\n");
}
}
- else if (!core_file_spec.empty())
+ else if (!m_option_data.m_core_file.empty())
{
- ::snprintf (command_string,
- sizeof(command_string),
- "target create %s",
- core_file_spec.c_str());
- m_debugger.HandleCommand (command_string);;
+ commands_stream.Printf("target create --core \"%s\"\n", m_option_data.m_core_file.c_str());
}
else if (!m_option_data.m_process_name.empty())
{
- ::snprintf (command_string,
- sizeof(command_string),
- "process attach --name '%s'%s",
- m_option_data.m_process_name.c_str(),
- m_option_data.m_wait_for ? " --waitfor" : "");
- m_debugger.HandleCommand (command_string);
+ commands_stream.Printf ("process attach --name \"%s\"", m_option_data.m_process_name.c_str());
+
+ if (m_option_data.m_wait_for)
+ commands_stream.Printf(" --waitfor");
+
+ commands_stream.Printf("\n");
+
}
else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
{
- ::snprintf (command_string,
- sizeof(command_string),
- "process attach --pid %" PRIu64,
- m_option_data.m_process_pid);
- m_debugger.HandleCommand (command_string);
+ commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
}
- ExecuteInitialCommands(false);
-
+ WriteInitialCommands(false, commands_stream);
+
// Now that all option parsing is done, we try and parse the .lldbinit
// file in the current working directory
sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
@@ -964,6 +912,90 @@ Driver::MainLoop ()
bool handle_events = true;
bool spawn_thread = false;
+
+ // Check if we have any data in the commands stream, and if so, save it to a temp file
+ // so we can then run the command interpreter using the file contents.
+ const char *commands_data = commands_stream.GetData();
+ const size_t commands_size = commands_stream.GetSize();
+ if (commands_data && commands_size)
+ {
+ enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
+
+ bool success = true;
+ int fds[2] = { -1, -1 };
+ int err = 0;
+#ifdef _WIN32
+ err = _pipe(fds, commands_size, O_BINARY);
+#else
+ err = pipe(fds);
+#endif
+ if (err == 0)
+ {
+ if (write (fds[WRITE], commands_data, commands_size) == commands_size)
+ {
+ // Close the write end of the pipe so when we give the read end to
+ // the debugger/command interpreter it will exit when it consumes all
+ // of the data
+#ifdef _WIN32
+ _close(fds[WRITE]); fds[WRITE] = -1;
+#else
+ close(fds[WRITE]); fds[WRITE] = -1;
+#endif
+ // Now open the read file descriptor in a FILE * that we can give to
+ // the debugger as an input handle
+ FILE *commands_file = fdopen(fds[READ], "r");
+ if (commands_file)
+ {
+ fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor
+ // Hand ownership if the FILE * over to the debugger for "commands_file".
+ m_debugger.SetInputFileHandle (commands_file, true);
+ m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
+ }
+ else
+ {
+ fprintf(stderr, "error: fdopen(%i, \"r\") failed (errno = %i) when trying to open LLDB commands pipe\n", fds[READ], errno);
+ success = false;
+ }
+ }
+ }
+ else
+ {
+ fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n");
+ success = false;
+ }
+
+ // Close any pipes that we still have ownership of
+ if ( fds[WRITE] != -1)
+ {
+#ifdef _WIN32
+ _close(fds[WRITE]); fds[WRITE] = -1;
+#else
+ close(fds[WRITE]); fds[WRITE] = -1;
+#endif
+
+ }
+
+ if ( fds[READ] != -1)
+ {
+#ifdef _WIN32
+ _close(fds[READ]); fds[READ] = -1;
+#else
+ close(fds[READ]); fds[READ] = -1;
+#endif
+ }
+
+ // Something went wrong with command pipe
+ if (!success)
+ {
+ exit(1);
+ }
+
+ }
+
+ // Now set the input file handle to STDIN and run the command
+ // interpreter again in interactive mode and let the debugger
+ // take ownership of stdin
+ m_debugger.SetInputFileHandle (stdin, true);
m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
reset_stdin_termios();
@@ -1032,6 +1064,12 @@ sigcont_handler (int signo)
int
main (int argc, char const *argv[], const char *envp[])
{
+#ifdef _MSC_VER
+ // disable buffering on windows
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stdin , NULL, _IONBF, 0);
+#endif
+
SBDebugger::Initialize();
SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
diff --git a/tools/driver/Driver.h b/tools/driver/Driver.h
index 699244685d06..8b6c6eebdd56 100644
--- a/tools/driver/Driver.h
+++ b/tools/driver/Driver.h
@@ -23,9 +23,6 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBError.h"
-#define ASYNC true
-#define NO_ASYNC false
-
class IOChannel;
class Driver : public lldb::SBBroadcaster
@@ -55,7 +52,7 @@ public:
GetScriptLanguage() const;
void
- ExecuteInitialCommands (bool before_file);
+ WriteInitialCommands (bool before_file, lldb::SBStream &strm);
bool
GetDebugMode() const;
diff --git a/tools/driver/Platform.cpp b/tools/driver/Platform.cpp
index 5b5286e68114..a49161540872 100644
--- a/tools/driver/Platform.cpp
+++ b/tools/driver/Platform.cpp
@@ -8,17 +8,14 @@
//===----------------------------------------------------------------------===//
// this file is only relevant for Visual C++
-#if defined( _MSC_VER )
+#if defined( _WIN32 )
#include <process.h>
#include <assert.h>
+#include <stdlib.h>
#include "Platform.h"
-// index one of the variable arguments
-// presuming "(EditLine *el, ..." is first in the argument list
-#define GETARG( Y, X ) ( (void* ) *( ( (int**) &(Y) ) + (X) ) )
-
// the control handler or SIGINT handler
static sighandler_t _ctrlHandler = NULL;
@@ -42,14 +39,16 @@ ioctl (int d, int request, ...)
// request the console windows size
case ( TIOCGWINSZ ):
{
- // locate the window size structure on stack
- winsize *ws = (winsize*) GETARG( d, 2 );
+ va_list vl;
+ va_start(vl,request);
+ // locate the window size structure on stack
+ winsize *ws = va_arg(vl, winsize*);
// get screen buffer information
CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info );
- // fill in the columns
- ws->ws_col = info.dwMaximumWindowSize.X;
- //
+ if ( GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info ) == TRUE )
+ // fill in the columns
+ ws->ws_col = info.dwMaximumWindowSize.X;
+ va_end(vl);
return 0;
}
break;
@@ -85,6 +84,7 @@ tcgetattr (int fildes, struct termios *termios_p)
return -1;
}
+#ifdef _MSC_VER
sighandler_t
signal (int sig, sighandler_t sigFunc)
{
@@ -107,5 +107,6 @@ signal (int sig, sighandler_t sigFunc)
}
return 0;
}
+#endif
-#endif \ No newline at end of file
+#endif
diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h
index faa2991bf6f3..e26610711aca 100644
--- a/tools/driver/Platform.h
+++ b/tools/driver/Platform.h
@@ -10,22 +10,18 @@
#ifndef lldb_Platform_h_
#define lldb_Platform_h_
-#if defined( _MSC_VER )
+#include "lldb/Host/HostGetOpt.h"
+
+#if defined( _WIN32 )
// this will stop signal.h being included
#define _INC_SIGNAL
-
#include <io.h>
+#if defined( _MSC_VER )
#include <eh.h>
+#endif
#include <inttypes.h>
- #include "lldb/Host/windows/Windows.h"
- #include "lldb/Host/HostGetOpt.h"
-
- struct timeval
- {
- long tv_sec;
- long tv_usec;
- };
+ #include "lldb/Host/windows/windows.h"
struct winsize
{
@@ -42,6 +38,17 @@
// ioctls.h
#define TIOCGWINSZ 0x5413
+
+ // signal handler function pointer type
+ typedef void(*sighandler_t)(int);
+
+ // signal.h
+ #define SIGINT 2
+ // default handler
+ #define SIG_DFL ( (sighandler_t) -1 )
+ // ignored
+ #define SIG_IGN ( (sighandler_t) -2 )
+
// signal.h
#define SIGPIPE 13
#define SIGCONT 18
@@ -64,34 +71,31 @@
speed_t c_ospeed; // output speed
};
- typedef long pid_t;
- #define STDIN_FILENO 0
- #define PATH_MAX MAX_PATH
+#ifdef _MSC_VER
+ struct timeval
+ {
+ long tv_sec;
+ long tv_usec;
+ };
+ typedef long pid_t;
#define snprintf _snprintf
+ extern sighandler_t signal( int sig, sighandler_t );
+ #define PATH_MAX MAX_PATH
+#endif
+
+ #define STDIN_FILENO 0
extern int ioctl( int d, int request, ... );
extern int kill ( pid_t pid, int sig );
extern int tcsetattr( int fd, int optional_actions, const struct termios *termios_p );
extern int tcgetattr( int fildes, struct termios *termios_p );
- // signal handler function pointer type
- typedef void (*sighandler_t)(int);
-
- // signal.h
- #define SIGINT 2
- // default handler
- #define SIG_DFL ( (sighandler_t) -1 )
- // ignored
- #define SIG_IGN ( (sighandler_t) -2 )
- extern sighandler_t signal( int sig, sighandler_t );
-
#else
#include <inttypes.h>
- #include <getopt.h>
#include <libgen.h>
#include <sys/ioctl.h>
#include <termios.h>
@@ -101,7 +105,7 @@
#include <pthread.h>
#include <sys/time.h>
- #if defined(__FreeBSD__)
+ #if defined(__FreeBSD__) || defined(__NetBSD__)
#include <readline/readline.h>
#else
#include <editline/readline.h>
diff --git a/tools/lldb-mi/Driver.cpp b/tools/lldb-mi/Driver.cpp
new file mode 100644
index 000000000000..a59b4b74eb0a
--- /dev/null
+++ b/tools/lldb-mi/Driver.cpp
@@ -0,0 +1,1299 @@
+//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// In-house headers:
+#include "MICmnConfig.h"
+
+#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
+
+#ifndef _MSC_VER
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <string>
+#endif // _MSC_VER
+
+#include "Platform.h" // CODETAG_IOR_SIGNALS
+#include "Driver.h"
+
+#ifdef _MSC_VER
+#include <lldb\Host\windows\getopt\GetOptInc.h>
+#endif // _MSC_VER
+#include <lldb/API/SBBreakpoint.h>
+#include <lldb/API/SBCommandInterpreter.h>
+#include <lldb/API/SBCommandReturnObject.h>
+#include <lldb/API/SBCommunication.h>
+#include <lldb/API/SBEvent.h>
+#include <lldb/API/SBHostOS.h>
+#include <lldb/API/SBListener.h>
+#include <lldb/API/SBStream.h>
+#include <lldb/API/SBTarget.h>
+#include <lldb/API/SBThread.h>
+#include <lldb/API/SBProcess.h>
+
+using namespace lldb;
+
+static void reset_stdin_termios ();
+static bool g_old_stdin_termios_is_valid = false;
+static struct termios g_old_stdin_termios;
+
+static char *g_debugger_name = (char *) "";
+Driver *g_driver = NULL;
+
+// In the Driver::MainLoop, we change the terminal settings. This function is
+// added as an atexit handler to make sure we clean them up.
+static void
+reset_stdin_termios ()
+{
+ if (g_old_stdin_termios_is_valid)
+ {
+ g_old_stdin_termios_is_valid = false;
+ ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
+ }
+}
+
+typedef struct
+{
+ uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
+ // then this option belongs to option set n.
+ bool required; // This option is required (in the current usage level)
+ const char * long_option; // Full name for this option.
+ int short_option; // Single character for this option.
+ int option_has_arg; // no_argument, required_argument or optional_argument
+ uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
+ lldb::CommandArgumentType argument_type; // Type of argument this option takes
+ const char * usage_text; // Full text explaining what this options does and what (if any) argument to
+ // pass it.
+} OptionDefinition;
+
+#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
+#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
+
+static OptionDefinition g_options[] =
+{
+ { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
+ "Prints out the usage information for the LLDB debugger." },
+ { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
+ "Prints out the current version number of the LLDB debugger." },
+ { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
+ "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
+ "be one of the architectures for which the program was compiled." },
+ { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to use the file <filename> as the program to be debugged." },
+ { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to use the fullpath to <path> as the core file." },
+ { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
+ "Tells the debugger to attach to a process with the given pid." },
+ { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
+ "Tells the debugger to attach to a process with the given name." },
+ { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
+ { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to read in and execute the lldb commands in the given file, after any file provided on the command line has been loaded." },
+ { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
+ "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded." },
+ { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to read in and execute the lldb commands in the given file, before any file provided on the command line has been loaded." },
+ { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
+ "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
+ { LLDB_3_TO_5, false, "source-quietly" , 'Q', no_argument , 0, eArgTypeNone,
+ "Tells the debugger suppress output from commands provided in the -s, -S, -O and -o commands." },
+ { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
+ { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
+ "Do not automatically parse any '.lldbinit' files." },
+ { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
+ "Do not use colors." },
+ { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
+ "Prints out the path to the lldb.py file for this version of lldb." },
+ { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
+ "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
+ "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
+ "extensions have been implemented." },
+ { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to print out extra information for debugging itself." },
+ { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
+};
+
+static const uint32_t last_option_set_with_args = 2;
+
+Driver::Driver () :
+ SBBroadcaster ("Driver"),
+ m_debugger (SBDebugger::Create(false)),
+ m_option_data ()
+{
+ // We want to be able to handle CTRL+D in the terminal to have it terminate
+ // certain input
+ m_debugger.SetCloseInputOnEOF (false);
+ g_debugger_name = (char *) m_debugger.GetInstanceName();
+ if (g_debugger_name == NULL)
+ g_debugger_name = (char *) "";
+ g_driver = this;
+}
+
+Driver::~Driver ()
+{
+ g_driver = NULL;
+ g_debugger_name = NULL;
+}
+
+
+// This function takes INDENT, which tells how many spaces to output at the front
+// of each line; TEXT, which is the text that is to be output. It outputs the
+// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
+// front of each line. It breaks lines on spaces, tabs or newlines, shortening
+// the line if necessary to not break in the middle of a word. It assumes that
+// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
+
+void
+OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
+{
+ int len = strlen (text);
+ std::string text_string (text);
+
+ // Force indentation to be reasonable.
+ if (indent >= output_max_columns)
+ indent = 0;
+
+ // Will it all fit on one line?
+
+ if (len + indent < output_max_columns)
+ // Output as a single line
+ fprintf (out, "%*s%s\n", indent, "", text);
+ else
+ {
+ // We need to break it up into multiple lines.
+ int text_width = output_max_columns - indent - 1;
+ int start = 0;
+ int end = start;
+ int final_end = len;
+ int sub_len;
+
+ while (end < final_end)
+ {
+ // Dont start the 'text' on a space, since we're already outputting the indentation.
+ while ((start < final_end) && (text[start] == ' '))
+ start++;
+
+ end = start + text_width;
+ if (end > final_end)
+ end = final_end;
+ else
+ {
+ // If we're not at the end of the text, make sure we break the line on white space.
+ while (end > start
+ && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
+ end--;
+ }
+ sub_len = end - start;
+ std::string substring = text_string.substr (start, sub_len);
+ fprintf (out, "%*s%s\n", indent, "", substring.c_str());
+ start = end + 1;
+ }
+ }
+}
+
+void
+ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
+{
+ uint32_t screen_width = 80;
+ uint32_t indent_level = 0;
+ const char *name = "lldb";
+
+ fprintf (out, "\nUsage:\n\n");
+
+ indent_level += 2;
+
+
+ // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
+ // <cmd> [options-for-level-1]
+ // etc.
+
+ uint32_t num_options;
+ uint32_t num_option_sets = 0;
+
+ for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
+ {
+ uint32_t this_usage_mask = option_table[num_options].usage_mask;
+ if (this_usage_mask == LLDB_OPT_SET_ALL)
+ {
+ if (num_option_sets == 0)
+ num_option_sets = 1;
+ }
+ else
+ {
+ for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
+ {
+ if (this_usage_mask & 1 << j)
+ {
+ if (num_option_sets <= j)
+ num_option_sets = j + 1;
+ }
+ }
+ }
+ }
+
+ for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
+ {
+ uint32_t opt_set_mask;
+
+ opt_set_mask = 1 << opt_set;
+
+ if (opt_set > 0)
+ fprintf (out, "\n");
+ fprintf (out, "%*s%s", indent_level, "", name);
+ bool is_help_line = false;
+
+ for (uint32_t i = 0; i < num_options; ++i)
+ {
+ if (option_table[i].usage_mask & opt_set_mask)
+ {
+ CommandArgumentType arg_type = option_table[i].argument_type;
+ const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
+ // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
+ // so we do it by hand here.
+ if (option_table[i].short_option == 'h')
+ is_help_line = true;
+
+ if (option_table[i].required)
+ {
+ if (option_table[i].option_has_arg == required_argument)
+ fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
+ else if (option_table[i].option_has_arg == optional_argument)
+ fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
+ else
+ fprintf (out, " -%c", option_table[i].short_option);
+ }
+ else
+ {
+ if (option_table[i].option_has_arg == required_argument)
+ fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
+ else if (option_table[i].option_has_arg == optional_argument)
+ fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
+ else
+ fprintf (out, " [-%c]", option_table[i].short_option);
+ }
+ }
+ }
+ if (!is_help_line && (opt_set <= last_option_set_with_args))
+ fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
+ }
+
+ fprintf (out, "\n\n");
+
+ // Now print out all the detailed information about the various options: long form, short form and help text:
+ // -- long_name <argument>
+ // - short <argument>
+ // help text
+
+ // This variable is used to keep track of which options' info we've printed out, because some options can be in
+ // more than one usage level, but we only want to print the long form of its information once.
+
+ Driver::OptionData::OptionSet options_seen;
+ Driver::OptionData::OptionSet::iterator pos;
+
+ indent_level += 5;
+
+ for (uint32_t i = 0; i < num_options; ++i)
+ {
+ // Only print this option if we haven't already seen it.
+ pos = options_seen.find (option_table[i].short_option);
+ if (pos == options_seen.end())
+ {
+ CommandArgumentType arg_type = option_table[i].argument_type;
+ const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
+
+ options_seen.insert (option_table[i].short_option);
+ fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
+ if (arg_type != eArgTypeNone)
+ fprintf (out, "<%s>", arg_name);
+ fprintf (out, "\n");
+ fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
+ if (arg_type != eArgTypeNone)
+ fprintf (out, "<%s>", arg_name);
+ fprintf (out, "\n");
+ indent_level += 5;
+ OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
+ indent_level -= 5;
+ fprintf (out, "\n");
+ }
+ }
+
+ indent_level -= 5;
+
+ fprintf (out, "\n%*sNotes:\n",
+ indent_level, "");
+ indent_level += 5;
+
+ fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, "
+ "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options."
+ "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out."
+ "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n",
+ indent_level, "",
+ indent_level, "",
+ indent_level, "",
+ indent_level, "");
+
+ fprintf (out, "\n%*sIf you don't provide -f then the first argument will be the file to be debugged"
+ "\n%*swhich means that '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
+ "\n%*sBut remember to end the options with \"--\" if any of your arguments have a \"-\" in them.\n\n",
+ indent_level, "",
+ indent_level, "",
+ name,
+ indent_level, "");
+}
+
+void
+BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
+ uint32_t num_options)
+{
+ if (num_options == 0)
+ return;
+
+ uint32_t i;
+ uint32_t j;
+ std::bitset<256> option_seen;
+
+ getopt_table.resize (num_options + 1);
+
+ for (i = 0, j = 0; i < num_options; ++i)
+ {
+ char short_opt = expanded_option_table[i].short_option;
+
+ if (option_seen.test(short_opt) == false)
+ {
+ getopt_table[j].name = expanded_option_table[i].long_option;
+ getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
+ getopt_table[j].flag = NULL;
+ getopt_table[j].val = expanded_option_table[i].short_option;
+ option_seen.set(short_opt);
+ ++j;
+ }
+ }
+
+ getopt_table[j].name = NULL;
+ getopt_table[j].has_arg = 0;
+ getopt_table[j].flag = NULL;
+ getopt_table[j].val = 0;
+
+}
+
+Driver::OptionData::OptionData () :
+ m_args(),
+ m_script_lang (lldb::eScriptLanguageDefault),
+ m_core_file (),
+ m_crash_log (),
+ m_initial_commands (),
+ m_after_file_commands (),
+ m_debug_mode (false),
+ m_source_quietly(false),
+ m_print_version (false),
+ m_print_python_path (false),
+ m_print_help (false),
+ m_wait_for(false),
+ m_process_name(),
+ m_process_pid(LLDB_INVALID_PROCESS_ID),
+ m_use_external_editor(false),
+ m_seen_options()
+{
+}
+
+Driver::OptionData::~OptionData ()
+{
+}
+
+void
+Driver::OptionData::Clear ()
+{
+ m_args.clear ();
+ m_script_lang = lldb::eScriptLanguageDefault;
+ m_initial_commands.clear ();
+ m_after_file_commands.clear ();
+ m_debug_mode = false;
+ m_source_quietly = false;
+ m_print_help = false;
+ m_print_version = false;
+ m_print_python_path = false;
+ m_use_external_editor = false;
+ m_wait_for = false;
+ m_process_name.erase();
+ m_process_pid = LLDB_INVALID_PROCESS_ID;
+}
+
+void
+Driver::OptionData::AddInitialCommand (const char *command, bool before_file, bool is_file, SBError &error)
+{
+ std::vector<std::pair<bool, std::string> > *command_set;
+ if (before_file)
+ command_set = &(m_initial_commands);
+ else
+ command_set = &(m_after_file_commands);
+
+ if (is_file)
+ {
+ SBFileSpec file(command);
+ if (file.Exists())
+ command_set->push_back (std::pair<bool, std::string> (true, optarg));
+ else if (file.ResolveExecutableLocation())
+ {
+ char final_path[PATH_MAX];
+ file.GetPath (final_path, sizeof(final_path));
+ std::string path_str (final_path);
+ command_set->push_back (std::pair<bool, std::string> (true, path_str));
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
+ }
+ else
+ command_set->push_back (std::pair<bool, std::string> (false, optarg));
+}
+
+void
+Driver::ResetOptionValues ()
+{
+ m_option_data.Clear ();
+}
+
+const char *
+Driver::GetFilename() const
+{
+ if (m_option_data.m_args.empty())
+ return NULL;
+ return m_option_data.m_args.front().c_str();
+}
+
+const char *
+Driver::GetCrashLogFilename() const
+{
+ if (m_option_data.m_crash_log.empty())
+ return NULL;
+ return m_option_data.m_crash_log.c_str();
+}
+
+lldb::ScriptLanguage
+Driver::GetScriptLanguage() const
+{
+ return m_option_data.m_script_lang;
+}
+
+void
+Driver::ExecuteInitialCommands (bool before_file)
+{
+ size_t num_commands;
+ std::vector<std::pair<bool, std::string> > *command_set;
+ if (before_file)
+ command_set = &(m_option_data.m_initial_commands);
+ else
+ command_set = &(m_option_data.m_after_file_commands);
+
+ num_commands = command_set->size();
+ SBCommandReturnObject result;
+ bool old_async = GetDebugger().GetAsync();
+ GetDebugger().SetAsync(false);
+ for (size_t idx = 0; idx < num_commands; idx++)
+ {
+ bool is_file = (*command_set)[idx].first;
+ const char *command = (*command_set)[idx].second.c_str();
+ char command_string[PATH_MAX * 2];
+ const bool dump_stream_only_if_no_immediate = true;
+ const char *executed_command = command;
+ if (is_file)
+ {
+ ::snprintf (command_string, sizeof(command_string), "command source -s %i '%s'", m_option_data.m_source_quietly, command);
+ executed_command = command_string;
+ }
+
+ m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false);
+ if (!m_option_data.m_source_quietly || result.Succeeded() == false)
+ {
+ const size_t output_size = result.GetOutputSize();
+ if (output_size > 0)
+ {
+ const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate);
+ if (cstr)
+ printf ("%s", cstr);
+ }
+ const size_t error_size = result.GetErrorSize();
+ if (error_size > 0)
+ {
+ const char *cstr = result.GetError(dump_stream_only_if_no_immediate);
+ if (cstr)
+ printf ("%s", cstr);
+ }
+ }
+
+ if (result.Succeeded() == false)
+ {
+ const char *type = before_file ? "before file" : "after_file";
+ if (is_file)
+ ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command);
+ else
+ ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command);
+ break;
+ }
+ result.Clear();
+ }
+ GetDebugger().SetAsync(old_async);
+}
+
+bool
+Driver::GetDebugMode() const
+{
+ return m_option_data.m_debug_mode;
+}
+
+
+// Check the arguments that were passed to this program to make sure they are valid and to get their
+// argument values (if any). Return a boolean value indicating whether or not to start up the full
+// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
+// if the user only wanted help or version information.
+
+SBError
+Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
+{
+ ResetOptionValues ();
+
+ SBCommandReturnObject result;
+
+ SBError error;
+ std::string option_string;
+ struct option *long_options = NULL;
+ std::vector<struct option> long_options_vector;
+ uint32_t num_options;
+
+ for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
+ /* Do Nothing. */;
+
+ if (num_options == 0)
+ {
+ if (argc > 1)
+ error.SetErrorStringWithFormat ("invalid number of options");
+ return error;
+ }
+
+ BuildGetOptTable (g_options, long_options_vector, num_options);
+
+ if (long_options_vector.empty())
+ long_options = NULL;
+ else
+ long_options = &long_options_vector.front();
+
+ if (long_options == NULL)
+ {
+ error.SetErrorStringWithFormat ("invalid long options");
+ return error;
+ }
+
+ // Build the option_string argument for call to getopt_long_only.
+
+ for (int i = 0; long_options[i].name != NULL; ++i)
+ {
+ if (long_options[i].flag == NULL)
+ {
+ option_string.push_back ((char) long_options[i].val);
+ switch (long_options[i].has_arg)
+ {
+ default:
+ case no_argument:
+ break;
+ case required_argument:
+ option_string.push_back (':');
+ break;
+ case optional_argument:
+ option_string.append ("::");
+ break;
+ }
+ }
+ }
+
+ // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
+ // know at that point whether we should read in init files yet. So we don't read them in in the
+ // Driver constructor, then set the flags back to "read them in" here, and then if we see the
+ // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
+ // main loop.
+
+ m_debugger.SkipLLDBInitFiles (false);
+ m_debugger.SkipAppInitFiles (false);
+
+ // Prepare for & make calls to getopt_long_only.
+#if __GLIBC__
+ optind = 0;
+#else
+ optreset = 1;
+ optind = 1;
+#endif
+ int val;
+ while (1)
+ {
+ int long_options_index = -1;
+ val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
+
+ if (val == -1)
+ break;
+ else if (val == '?')
+ {
+ m_option_data.m_print_help = true;
+ error.SetErrorStringWithFormat ("unknown or ambiguous option");
+ break;
+ }
+ else if (val == 0)
+ continue;
+ else
+ {
+ m_option_data.m_seen_options.insert ((char) val);
+ if (long_options_index == -1)
+ {
+ for (int i = 0;
+ long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
+ ++i)
+ {
+ if (long_options[i].val == val)
+ {
+ long_options_index = i;
+ break;
+ }
+ }
+ }
+
+ if (long_options_index >= 0)
+ {
+ const int short_option = g_options[long_options_index].short_option;
+
+ switch (short_option)
+ {
+ case 'h':
+ m_option_data.m_print_help = true;
+ break;
+
+ case 'v':
+ m_option_data.m_print_version = true;
+ break;
+
+ case 'P':
+ m_option_data.m_print_python_path = true;
+ break;
+
+ case 'c':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ {
+ m_option_data.m_core_file = optarg;
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
+ }
+ break;
+
+ case 'e':
+ m_option_data.m_use_external_editor = true;
+ break;
+
+ case 'x':
+ m_debugger.SkipLLDBInitFiles (true);
+ m_debugger.SkipAppInitFiles (true);
+ break;
+
+ case 'X':
+ m_debugger.SetUseColor (false);
+ break;
+
+ case 'f':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ {
+ m_option_data.m_args.push_back (optarg);
+ }
+ else if (file.ResolveExecutableLocation())
+ {
+ char path[PATH_MAX];
+ file.GetPath (path, sizeof(path));
+ m_option_data.m_args.push_back (path);
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
+ }
+ break;
+
+ case 'a':
+ if (!m_debugger.SetDefaultArchitecture (optarg))
+ error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
+ break;
+
+ case 'l':
+ m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
+ break;
+
+ case 'd':
+ m_option_data.m_debug_mode = true;
+ break;
+
+ case 'Q':
+ m_option_data.m_source_quietly = true;
+ break;
+
+ case 'n':
+ m_option_data.m_process_name = optarg;
+ break;
+
+ case 'w':
+ m_option_data.m_wait_for = true;
+ break;
+
+ case 'p':
+ {
+ char *remainder;
+ m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
+ if (remainder == optarg || *remainder != '\0')
+ error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
+ optarg);
+ }
+ break;
+ case 's':
+ m_option_data.AddInitialCommand(optarg, false, true, error);
+ break;
+ case 'o':
+ m_option_data.AddInitialCommand(optarg, false, false, error);
+ break;
+ case 'S':
+ m_option_data.AddInitialCommand(optarg, true, true, error);
+ break;
+ case 'O':
+ m_option_data.AddInitialCommand(optarg, true, false, error);
+ break;
+ default:
+ m_option_data.m_print_help = true;
+ error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
+ break;
+ }
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("invalid option with value %i", val);
+ }
+ if (error.Fail())
+ {
+ return error;
+ }
+ }
+ }
+
+ if (error.Fail() || m_option_data.m_print_help)
+ {
+ ShowUsage (out_fh, g_options, m_option_data);
+ exiting = true;
+ }
+ else if (m_option_data.m_print_version)
+ {
+ ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
+ exiting = true;
+ }
+ else if (m_option_data.m_print_python_path)
+ {
+ SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
+ if (python_file_spec.IsValid())
+ {
+ char python_path[PATH_MAX];
+ size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
+ if (num_chars < PATH_MAX)
+ {
+ ::fprintf (out_fh, "%s\n", python_path);
+ }
+ else
+ ::fprintf (out_fh, "<PATH TOO LONG>\n");
+ }
+ else
+ ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
+ exiting = true;
+ }
+ else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
+ {
+ // Any arguments that are left over after option parsing are for
+ // the program. If a file was specified with -f then the filename
+ // is already in the m_option_data.m_args array, and any remaining args
+ // are arguments for the inferior program. If no file was specified with
+ // -f, then what is left is the program name followed by any arguments.
+
+ // Skip any options we consumed with getopt_long_only
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0)
+ {
+ for (int arg_idx=0; arg_idx<argc; ++arg_idx)
+ {
+ const char *arg = argv[arg_idx];
+ if (arg)
+ m_option_data.m_args.push_back (arg);
+ }
+ }
+
+ }
+ else
+ {
+ // Skip any options we consumed with getopt_long_only
+ argc -= optind;
+ //argv += optind; // Commented out to keep static analyzer happy
+
+ if (argc > 0)
+ ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
+ }
+
+ return error;
+}
+
+void
+Driver::MainLoop ()
+{
+ if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
+ {
+ g_old_stdin_termios_is_valid = true;
+ atexit (reset_stdin_termios);
+ }
+
+ ::setbuf (stdin, NULL);
+ ::setbuf (stdout, NULL);
+
+ m_debugger.SetErrorFileHandle (stderr, false);
+ m_debugger.SetOutputFileHandle (stdout, false);
+ m_debugger.SetInputFileHandle (stdin, true);
+
+ m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
+
+ struct winsize window_size;
+ if (isatty (STDIN_FILENO)
+ && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
+ {
+ if (window_size.ws_col > 0)
+ m_debugger.SetTerminalWidth (window_size.ws_col);
+ }
+
+ SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
+
+ // Before we handle any options from the command line, we parse the
+ // .lldbinit file in the user's home directory.
+ SBCommandReturnObject result;
+ sb_interpreter.SourceInitFileInHomeDirectory(result);
+ if (GetDebugMode())
+ {
+ result.PutError (m_debugger.GetErrorFileHandle());
+ result.PutOutput (m_debugger.GetOutputFileHandle());
+ }
+
+ // Now we handle options we got from the command line
+ // First source in the commands specified to be run before the file arguments are processed.
+ ExecuteInitialCommands(true);
+
+ // Was there a core file specified?
+ std::string core_file_spec("");
+ if (!m_option_data.m_core_file.empty())
+ core_file_spec.append("--core ").append(m_option_data.m_core_file);
+
+ char command_string[PATH_MAX * 2];
+ const size_t num_args = m_option_data.m_args.size();
+ if (num_args > 0)
+ {
+ char arch_name[64];
+ if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
+ ::snprintf (command_string,
+ sizeof (command_string),
+ "target create --arch=%s %s \"%s\"",
+ arch_name,
+ core_file_spec.c_str(),
+ m_option_data.m_args[0].c_str());
+ else
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "target create %s \"%s\"",
+ core_file_spec.c_str(),
+ m_option_data.m_args[0].c_str());
+
+ m_debugger.HandleCommand (command_string);
+
+ if (num_args > 1)
+ {
+ m_debugger.HandleCommand ("settings clear target.run-args");
+ char arg_cstr[1024];
+ for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
+ {
+ ::snprintf (arg_cstr,
+ sizeof(arg_cstr),
+ "settings append target.run-args \"%s\"",
+ m_option_data.m_args[arg_idx].c_str());
+ m_debugger.HandleCommand (arg_cstr);
+ }
+ }
+ }
+ else if (!core_file_spec.empty())
+ {
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "target create %s",
+ core_file_spec.c_str());
+ m_debugger.HandleCommand (command_string);;
+ }
+ else if (!m_option_data.m_process_name.empty())
+ {
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "process attach --name '%s'%s",
+ m_option_data.m_process_name.c_str(),
+ m_option_data.m_wait_for ? " --waitfor" : "");
+ m_debugger.HandleCommand (command_string);
+ }
+ else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
+ {
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "process attach --pid %" PRIu64,
+ m_option_data.m_process_pid);
+ m_debugger.HandleCommand (command_string);
+ }
+
+ ExecuteInitialCommands(false);
+
+ // Now that all option parsing is done, we try and parse the .lldbinit
+ // file in the current working directory
+ sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
+ if (GetDebugMode())
+ {
+ result.PutError(m_debugger.GetErrorFileHandle());
+ result.PutOutput(m_debugger.GetOutputFileHandle());
+ }
+
+ bool handle_events = true;
+ bool spawn_thread = false;
+ m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
+
+ reset_stdin_termios();
+ fclose (stdin);
+
+ SBDebugger::Destroy (m_debugger);
+}
+
+void
+Driver::ResizeWindow (unsigned short col)
+{
+ GetDebugger().SetTerminalWidth (col);
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Setup *this driver so it works as pass through (child) driver for the MI
+// driver. Called by the parent (MI driver) driver.
+// This driver has setup code in two places. The original in MainLoop() and
+// in int main() (when MICONFIG_COMPILE_MIDRIVER_VERSION == 0) so that code can
+// remain as much near to the original code as possible. If MI driver is the main
+// driver (when MICONFIG_COMPILE_MIDRIVER_VERSION == 1) then this function is
+// used to set up the Driver to work with the MI driver.
+// Type: Method.
+// Args: vwErrMsg - (W) On failure current error discription.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::MISetup( CMIUtilString & vwErrMsg )
+{
+ bool bOk = MIstatus::success;
+
+ // Is *this driver a pass through driver to the MI driver
+ CMIDriverBase * pParent = GetDriversParent();
+ if( pParent == nullptr )
+ {
+ // No it is not.
+ // If MI is the main driver (which passes through to *this driver) then
+ // *this driver needs to be initialized after MI is initialize to have a valid
+ // pointer to the parent driver. *this is the parent's pass thru driver.
+ assert( pParent == nullptr );
+ return MIstatus::success; // Allow success for if Driver is the main driver
+ }
+
+ // MI driver may have streams it wants *this driver to use - still to be sorted
+ m_debugger.SetErrorFileHandle( pParent->GetStderr(), false ); // MI may redirect to its own stream
+ m_debugger.SetOutputFileHandle( pParent->GetStdout(), false ); // MI likely to NULL this
+ m_debugger.SetInputFileHandle( pParent->GetStdin(), false ); // MI could use this to feed input
+
+ // ToDo: Do I need this?
+ m_debugger.SetUseExternalEditor( m_option_data.m_use_external_editor );
+
+ // ToDo: Do I need this?
+ struct winsize window_size;
+ if( isatty( STDIN_FILENO ) && ::ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) == 0 )
+ {
+ if( window_size.ws_col > 0 )
+ m_debugger.SetTerminalWidth( window_size.ws_col );
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Initialize setup *this driver ready for use.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::DoInitialize( void )
+{
+ // Do nothing
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Unbind detach or release resources used by *this driver.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::DoShutdown( void )
+{
+ SBDebugger::Destroy( m_debugger );
+
+ // Is *this driver a pass through driver to the MI driver
+ CMIDriverBase * pParent = GetDriversParent();
+ if( pParent == nullptr )
+ {
+ // See DoInitialize().
+ assert( pParent == nullptr );
+ return MIstatus::success;
+ }
+
+ // Put stuff here when *this driver is a pass thru driver to the MI driver
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the name for *this driver.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - Driver name.
+// Throws: None.
+//--
+const CMIUtilString & Driver::GetName( void ) const
+{
+ static CMIUtilString name( "LLDB driver" );
+ return name;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve *this driver's last error condition.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString - Text description.
+// Throws: None.
+//--
+CMIUtilString Driver::GetError( void ) const
+{
+ // Do nothing - to implement
+ return CMIUtilString();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Call this function puts *this driver to work.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::DoMainLoop( void )
+{
+ MainLoop();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Call *this driver to resize the console window.
+// Type: Overridden.
+// Args: vTermWidth - (R) New window column size.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+void Driver::DoResizeWindow( const uint32_t vTermWidth )
+{
+ ResizeWindow( (unsigned short) vTermWidth );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Call *this driver to return it's debugger.
+// Type: Overridden.
+// Args: None.
+// Return: lldb::SBDebugger & - LLDB debugger object reference.
+// Throws: None.
+//--
+lldb::SBDebugger & Driver::GetTheDebugger( void )
+{
+ return GetDebugger();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Proxy function to allow the driver implementation to validate executable
+// command line arguments.
+// Type: Overrideable.
+// Args: argc - (R) An integer that contains the count of arguments that follow in
+// argv. The argc parameter is always greater than or equal to 1.
+// argv - (R) An array of null-terminated strings representing command-line
+// arguments entered by the user of the program. By convention,
+// argv[0] is the command with which the program is invoked.
+// vpStdOut - (R) Pointer to a standard output stream.
+// vwbExiting - (W) True = *this want to exit, Reasons: help, invalid arg(s),
+// version information only.
+// False = Continue to work, start debugger i.e. Command
+// interpreter.
+// Return: lldb::SBError - LLDB current error status.
+// Throws: None.
+//--
+lldb::SBError Driver::DoParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting )
+{
+ return ParseArgs( argc, argv, vpStdOut, vwbExiting );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: A client can ask if *this driver is GDB/MI compatible.
+// Type: Overridden.
+// Args: None.
+// Return: True - GBD/MI compatible LLDB front end.
+// False - Not GBD/MI compatible LLDB front end.
+// Throws: None.
+//--
+bool Driver::GetDriverIsGDBMICompatibleDriver( void ) const
+{
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: This function allows *this driver to call on another driver to perform work
+// should this driver not be able to handle the client data input.
+// SetDriverToFallThruTo() specifies the fall through to driver.
+// Check the error message if the function returns a failure.
+// Type: Overridden.
+// Args: vCmd - (R) Command instruction to interpret.
+// vwErrMsg - (W) Error description on command failing.
+// Return: MIstatus::success - Command succeeded.
+// MIstatus::failure - Command failed.
+// Throws: None.
+//--
+bool Driver::DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilString & vwErrMsg )
+{
+ bool bOk = MIstatus::success;
+ vwErrMsg.empty();
+
+ // ToDo: Implement do work on other driver after this driver said "Give up you try"
+ // This may nto be required if the feature to 'fall through' is not required
+ SBCommandReturnObject returnObj = lldb::SBCommandReturnObject();
+ SBCommandInterpreter cmdIntrp = m_debugger.GetCommandInterpreter();
+ const lldb::ReturnStatus cmdResult = cmdIntrp.HandleCommand( vCmd.c_str(), returnObj ); MIunused( cmdResult );
+ if( returnObj.Succeeded() == false )
+ {
+ bOk = MIstatus::failure;
+ vwErrMsg = returnObj.GetError();
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: This function allows *this driver to call functionality on the parent driver
+// ask for information for example.
+// Type: Overridden.
+// Args: vrOtherDriver - (R) Reference to another driver object.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::SetDriverParent( const CMIDriverBase & vrOtherDriver )
+{
+ m_pDriverParent = const_cast< CMIDriverBase * >( &vrOtherDriver );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Set a unique ID for *this driver. It cannot be empty.
+// Type: Overridden.
+// Args: vId - (R) Text description.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool Driver::SetId( const CMIUtilString & vId )
+{
+ if( vId.empty() )
+ {
+ // Invalid to have it empty
+ return MIstatus::failure;
+ }
+
+ m_strDriverId = vId;
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get the unique ID for *this driver.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - Text description.
+// Throws: None.
+//--
+const CMIUtilString & Driver::GetId( void ) const
+{
+ return m_strDriverId;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Create *this driver. Function contains functionality that needs to be called
+// prior to constructing the *this driver.
+// Type: Static method.
+// Args: None.
+// Return: Driver * - Ptr to the LLDB driver object.
+// Throws: None.
+//--
+Driver * Driver::CreateSelf( void )
+{
+ lldb::SBDebugger::Initialize();
+
+ Driver * pDriver = new Driver;
+ return pDriver;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the name for *this driver.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString - Driver name.
+// Throws: None.
+//--
+const CMIUtilString & Driver::GetDriverName( void ) const
+{
+ return GetName();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get the unique ID for *this driver.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - Text description.
+// Throws: None.
+//--
+const CMIUtilString & Driver::GetDriverId( void ) const
+{
+ return GetId();
+}
+
+#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
+
diff --git a/tools/lldb-mi/Driver.h b/tools/lldb-mi/Driver.h
new file mode 100644
index 000000000000..39577c49bf05
--- /dev/null
+++ b/tools/lldb-mi/Driver.h
@@ -0,0 +1,163 @@
+//===-- Driver.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// In-house headers:
+#include "MICmnConfig.h"
+#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
+
+#ifndef lldb_Driver_h_
+#define lldb_Driver_h_
+
+//#include "Platform.h" // IOR removed
+#include <lldb/Utility/PseudoTerminal.h>
+
+#include <set>
+#include <bitset>
+#include <string>
+#include <vector>
+
+#include <lldb/API/SBDefines.h>
+#include <lldb/API/SBBroadcaster.h>
+#include <lldb/API/SBDebugger.h>
+#include <lldb/API/SBError.h>
+#include "MIDriverMgr.h"
+#include "MIDriverBase.h"
+
+#define ASYNC true
+#define NO_ASYNC false
+
+class IOChannel;
+
+class Driver : public lldb::SBBroadcaster, public CMIDriverBase, public CMIDriverMgr::IDriver
+{
+// MI required code:
+// Static:
+public:
+ static Driver * CreateSelf( void );
+
+// Methods:
+public:
+ bool MISetup( CMIUtilString & vwErrMsg );
+
+// Overridden:
+public:
+ // From CMIDriverMgr::IDriver
+ virtual bool DoInitialize( void );
+ virtual bool DoShutdown( void );
+ virtual bool DoMainLoop( void );
+ virtual void DoResizeWindow( const uint32_t vWindowSizeWsCol );
+ virtual lldb::SBError DoParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting );
+ virtual CMIUtilString GetError( void ) const;
+ virtual const CMIUtilString & GetName( void ) const;
+ virtual lldb::SBDebugger & GetTheDebugger( void );
+ virtual bool GetDriverIsGDBMICompatibleDriver( void ) const;
+ virtual bool SetId( const CMIUtilString & vID );
+ virtual const CMIUtilString & GetId( void ) const;
+ // From CMIDriverBase
+ virtual bool DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilString & vwErrMsg );
+ virtual bool SetDriverParent( const CMIDriverBase & vrOtherDriver );
+ virtual const CMIUtilString & GetDriverName( void ) const;
+ virtual const CMIUtilString & GetDriverId( void ) const;
+
+// Original code:
+public:
+ Driver ();
+
+ virtual
+ ~Driver ();
+
+ void
+ MainLoop ();
+
+ lldb::SBError
+ ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);
+
+ const char *
+ GetFilename() const;
+
+ const char *
+ GetCrashLogFilename() const;
+
+ const char *
+ GetArchName() const;
+
+ lldb::ScriptLanguage
+ GetScriptLanguage() const;
+
+ void
+ ExecuteInitialCommands (bool before_file);
+
+ bool
+ GetDebugMode() const;
+
+ class OptionData
+ {
+ public:
+ OptionData ();
+ ~OptionData ();
+
+ void
+ Clear();
+
+ void
+ AddInitialCommand (const char *command, bool before_file, bool is_file, lldb::SBError &error);
+
+ //static OptionDefinition m_cmd_option_table[];
+
+ std::vector<std::string> m_args;
+ lldb::ScriptLanguage m_script_lang;
+ std::string m_core_file;
+ std::string m_crash_log;
+ std::vector<std::pair<bool,std::string> > m_initial_commands;
+ std::vector<std::pair<bool,std::string> > m_after_file_commands;
+ bool m_debug_mode;
+ bool m_source_quietly;
+ bool m_print_version;
+ bool m_print_python_path;
+ bool m_print_help;
+ bool m_wait_for;
+ std::string m_process_name;
+ lldb::pid_t m_process_pid;
+ bool m_use_external_editor; // FIXME: When we have set/show variables we can remove this from here.
+ typedef std::set<char> OptionSet;
+ OptionSet m_seen_options;
+ };
+
+
+ static lldb::SBError
+ SetOptionValue (int option_idx,
+ const char *option_arg,
+ Driver::OptionData &data);
+
+
+ lldb::SBDebugger &
+ GetDebugger()
+ {
+ return m_debugger;
+ }
+
+ void
+ ResizeWindow (unsigned short col);
+
+private:
+ lldb::SBDebugger m_debugger;
+ OptionData m_option_data;
+
+ void
+ ResetOptionValues ();
+
+ void
+ ReadyForCommand ();
+};
+
+extern Driver * g_driver;
+
+#endif // lldb_Driver_h_
+
+#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
diff --git a/tools/lldb-mi/MICmdArgContext.cpp b/tools/lldb-mi/MICmdArgContext.cpp
new file mode 100644
index 000000000000..b6efa9660c3b
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgContext.cpp
@@ -0,0 +1,255 @@
+//===-- MICmnArgContext.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmnArgContext.cpp
+//
+// Overview: CMICmdArgContext implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgContext constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgContext::CMICmdArgContext( void )
+: m_constCharSpace( ' ' )
+, m_constStrSpace( " " )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgContext constructor.
+// Type: Method.
+// Args: vrCmdLineArgsRaw - (R) The text description of the arguments options.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgContext::CMICmdArgContext( const CMIUtilString & vrCmdLineArgsRaw )
+: m_strCmdArgsAndOptions( vrCmdLineArgsRaw )
+, m_constCharSpace( ' ' )
+, m_constStrSpace( " " )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgContext destructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgContext::~CMICmdArgContext( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the remainder of the command's argument options left to parse.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString & - Argument options text.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdArgContext::GetArgsLeftToParse( void ) const
+{
+ return m_strCmdArgsAndOptions;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Ask if this arguments string has any arguments.
+// Type: Method.
+// Args: None.
+// Return: bool - True = Has one or more arguments present, false = no arguments.
+// Throws: None.
+//--
+bool CMICmdArgContext::IsEmpty( void ) const
+{
+ return m_strCmdArgsAndOptions.empty();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Remove the argument from the options text and any space after the argument
+// if applicable.
+// Type: Method.
+// Args: vArg - (R) The name of the argument.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgContext::RemoveArg( const CMIUtilString & vArg )
+{
+ if( vArg.empty() )
+ return MIstatus::success;
+
+ const MIuint nLen = vArg.length();
+ const MIuint nLenCntxt = m_strCmdArgsAndOptions.length();
+ if( nLen > nLenCntxt )
+ return MIstatus::failure;
+
+ MIuint nExtraSpace = 0;
+ MIint nPos = m_strCmdArgsAndOptions.find( vArg );
+ while( 1 )
+ {
+ if( nPos == (MIint) std::string::npos )
+ return MIstatus::success;
+
+ bool bPass1 = false;
+ if( nPos != 0 )
+ {
+ if( m_strCmdArgsAndOptions[ nPos - 1 ] == m_constCharSpace )
+ bPass1 = true;
+ }
+ else
+ bPass1 = true;
+
+ const MIuint nEnd = nPos + nLen;
+
+ if( bPass1 )
+ {
+ bool bPass2 = false;
+ if( nEnd < nLenCntxt )
+ {
+ if( m_strCmdArgsAndOptions[ nEnd ] == m_constCharSpace )
+ {
+ bPass2 = true;
+ nExtraSpace = 1;
+ }
+ }
+ else
+ bPass2 = true;
+
+ if( bPass2 )
+ break;
+ }
+
+ nPos = m_strCmdArgsAndOptions.find( vArg, nEnd );
+ }
+
+ const MIuint nPosEnd = nLen + nExtraSpace;
+ m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.replace( nPos, nPosEnd, "" ).c_str();
+ m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Remove the argument at the Nth word position along in the context string.
+// Any space after the argument is removed if applicable. A search is not
+// performed as there may be more than one vArg with the same 'name' in the
+// context string.
+// Type: Method.
+// Args: vArg - (R) The name of the argument.
+// nArgIndex - (R) The word count position to which to remove the vArg word.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgContext::RemoveArgAtPos( const CMIUtilString & vArg, const MIuint nArgIndex )
+{
+ MIuint nWordIndex = 0;
+ CMIUtilString strBuildContextUp;
+ const CMIUtilString::VecString_t vecWords( GetArgs() );
+ const bool bSpaceRequired( GetNumberArgsPresent() > 2 );
+
+ CMIUtilString::VecString_t::const_iterator it = vecWords.begin();
+ const CMIUtilString::VecString_t::const_iterator itEnd = vecWords.end();
+ while( it != itEnd )
+ {
+ const CMIUtilString & rWord( *it );
+ if( nWordIndex++ != nArgIndex )
+ {
+ // Single words
+ strBuildContextUp += rWord;
+ if( bSpaceRequired )
+ strBuildContextUp += m_constStrSpace;
+ }
+ else
+ {
+ // If quoted loose quoted text
+ if( ++it != itEnd )
+ {
+ CMIUtilString words = rWord;
+ while( vArg != words )
+ {
+ if( bSpaceRequired )
+ words += m_constStrSpace;
+ words += *it;
+ if( ++it == itEnd )
+ break;
+ }
+ if( it != itEnd )
+ --it;
+ }
+ }
+
+ // Next
+ if( it != itEnd )
+ ++it;
+ }
+
+ m_strCmdArgsAndOptions = strBuildContextUp;
+ m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve number of arguments or options present in the command's option text.
+// Type: Method.
+// Args: None.
+// Return: MIuint - 0 to n arguments present.
+// Throws: None.
+//--
+MIuint CMICmdArgContext::GetNumberArgsPresent( void ) const
+{
+ CMIUtilString::VecString_t vecOptions;
+ return m_strCmdArgsAndOptions.SplitConsiderQuotes( m_constStrSpace, vecOptions );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve all the arguments or options remaining in *this context.
+// Type: Method.
+// Args: None.
+// Return: MIUtilString::VecString_t - List of args remaining.
+// Throws: None.
+//--
+CMIUtilString::VecString_t CMICmdArgContext::GetArgs( void ) const
+{
+ CMIUtilString::VecString_t vecOptions;
+ m_strCmdArgsAndOptions.SplitConsiderQuotes( m_constStrSpace, vecOptions );
+ return vecOptions;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Copy assignment operator.
+// Type: Method.
+// Args: vOther - (R) The variable to copy from.
+// Return: CMIUtilString & - this object.
+// Throws: None.
+//--
+CMICmdArgContext & CMICmdArgContext::operator= ( const CMICmdArgContext & vOther )
+{
+ if( this != &vOther )
+ {
+ m_strCmdArgsAndOptions = vOther.m_strCmdArgsAndOptions;
+ }
+
+ return *this;
+} \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdArgContext.h b/tools/lldb-mi/MICmdArgContext.h
new file mode 100644
index 000000000000..699bac13e014
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgContext.h
@@ -0,0 +1,61 @@
+//===-- MICmdArgContext.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgContext.h
+//
+// Overview: CMICmdArgContext interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MIUtilString.h"
+
+//++ ============================================================================
+// Details: MI common code class. Command arguments and options string. Holds
+// the context string.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 14/04/2014.
+// Changes: None.
+//--
+class CMICmdArgContext
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgContext( void );
+ /* ctor */ CMICmdArgContext( const CMIUtilString & vrCmdLineArgsRaw );
+ //
+ const CMIUtilString & GetArgsLeftToParse( void ) const;
+ MIuint GetNumberArgsPresent( void ) const;
+ CMIUtilString::VecString_t GetArgs( void ) const;
+ bool IsEmpty( void ) const;
+ bool RemoveArg( const CMIUtilString & vArg );
+ bool RemoveArgAtPos( const CMIUtilString & vArg, const MIuint nArgIndex );
+ //
+ CMICmdArgContext & operator= ( const CMICmdArgContext & vOther );
+
+// Overridden:
+public:
+ // From CMIUtilString
+ /* dtor */ virtual ~CMICmdArgContext( void );
+
+// Attributes:
+private:
+ CMIUtilString m_strCmdArgsAndOptions;
+ const MIchar m_constCharSpace;
+ const CMIUtilString m_constStrSpace;
+};
diff --git a/tools/lldb-mi/MICmdArgSet.cpp b/tools/lldb-mi/MICmdArgSet.cpp
new file mode 100644
index 000000000000..b0bee357cd6b
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgSet.cpp
@@ -0,0 +1,420 @@
+//===-- MICmdArgSet.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgSet.cpp
+//
+// Overview: CMICmdArgSet implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgSet.h"
+#include "MICmdArgValBase.h"
+#include "MICmnResources.h"
+#include "MICmnLog.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgSet constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgSet::CMICmdArgSet( void )
+: m_bIsArgsPresentButNotHandledByCmd( false )
+, m_constStrCommaSpc( ", " )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgSet destructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgSet::~CMICmdArgSet( void )
+{
+ // Tidy up
+ Destroy();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Release resources used by *this container object.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdArgSet::Destroy( void )
+{
+ // Delete command argument objects
+ if( !m_setCmdArgs.empty() )
+ {
+ SetCmdArgs_t::iterator it = m_setCmdArgs.begin();
+ while( it != m_setCmdArgs.end() )
+ {
+ CMICmdArgValBase * pArg( *it );
+ delete pArg;
+
+ // Next
+ ++it;
+ }
+ m_setCmdArgs.clear();
+ }
+
+ m_setCmdArgsThatNotValid.clear();
+ m_setCmdArgsThatAreMissing.clear();
+ m_setCmdArgsNotHandledByCmd.clear();
+ m_setCmdArgsMissingInfo.clear();
+ m_bIsArgsPresentButNotHandledByCmd = false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag indicating that the command set up ready to parse
+// command arguments or options found that one or more arguments was indeed
+// present but not handled. This is given as a warning in the MI log file.
+// Type: Method.
+// Args: None.
+// Return: bool - True = one or more args not handled, false = all args handled
+// Throws: None.
+//--
+bool CMICmdArgSet::IsArgsPresentButNotHandledByCmd( void ) const
+{
+ return m_bIsArgsPresentButNotHandledByCmd;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Add the list of command's arguments to parse and validate another one.
+// Type: Method.
+// Args: vArg - (R) A command argument object.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgSet::Add( const CMICmdArgValBase & vArg )
+{
+ CMICmdArgValBase * pArg = const_cast< CMICmdArgValBase * >( &vArg );
+ m_setCmdArgs.push_back( pArg );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: After validating an options line of text (the context) and there is a failure,
+// it is likely a mandatory command argument that is required is missing. This
+// function returns the argument that should be present.
+// Type: Method.
+// Args: None.
+// Return: SetCmdArgs_t & - Set of argument objects.
+// Throws: None.
+//--
+const CMICmdArgSet::SetCmdArgs_t & CMICmdArgSet::GetArgsThatAreMissing( void ) const
+{
+ return m_setCmdArgsThatAreMissing;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: After validating an options line of text (the context) and there is a failure,
+// it may be because one or more arguments were unable to extract a value. This
+// function returns the argument that were found to be invalid.
+// Type: Method.
+// Args: None.
+// Return: SetCmdArgs_t & - Set of argument objects.
+// Throws: None.
+//--
+const CMICmdArgSet::SetCmdArgs_t & CMICmdArgSet::GetArgsThatInvalid( void ) const
+{
+ return m_setCmdArgsThatNotValid;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The list of argument or option (objects) that were specified by the command
+// and so recognised when parsed but were not handled. Ideally the command
+// should handle all arguments and options presented to it. The command sends
+// warning to the MI log file to say that these options were not handled.
+// Used as one way to determine option that maybe should really be implemented
+// and not just ignored.
+// Type: Method.
+// Args: None.
+// Return: SetCmdArgs_t & - Set of argument objects.
+// Throws: None.
+//--
+const CMICmdArgSet::SetCmdArgs_t & CMICmdArgSet::GetArgsNotHandledByCmd( void ) const
+{
+ return m_setCmdArgsNotHandledByCmd;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Given a set of command argument objects parse the context option string to
+// find those argument and retrieve their value. If the function fails call
+// GetArgsThatAreMissing() to see which commands that were mandatory were
+// missing or failed to parse.
+// Type: Method.
+// Args: vStrMiCmd - (R) Command's name.
+// vCmdArgsText - (RW) A command's options or argument.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgSet::Validate( const CMIUtilString & vStrMiCmd, CMICmdArgContext & vwCmdArgsText )
+{
+ m_cmdArgContext = vwCmdArgsText;
+
+ // Iterate all the arguments or options required by a command
+ const MIuint nArgs = vwCmdArgsText.GetNumberArgsPresent();
+ MIuint nArgsMandatoryCnt = 0;
+ SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
+ while( it != m_setCmdArgs.end() )
+ {
+ const CMICmdArgValBase * pArg( *it );
+ const CMIUtilString & rArgName( pArg->GetName() ); MIunused( rArgName );
+ if( pArg->GetIsMandatory() )
+ nArgsMandatoryCnt++;
+ if( !const_cast< CMICmdArgValBase * >( pArg )->Validate( vwCmdArgsText ) )
+ {
+ if( pArg->GetIsMandatory() && !pArg->GetFound() )
+ m_setCmdArgsThatAreMissing.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
+ else if( pArg->GetFound() )
+ {
+ if( pArg->GetIsMissingOptions() )
+ m_setCmdArgsMissingInfo.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
+ else if( !pArg->GetValid() )
+ m_setCmdArgsThatNotValid.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
+ }
+ }
+ if( pArg->GetFound() && !pArg->GetIsHandledByCmd() )
+ {
+ m_bIsArgsPresentButNotHandledByCmd = true;
+ m_setCmdArgsNotHandledByCmd.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
+ }
+
+ // Next
+ ++it;
+ }
+
+ // Check that one or more argument objects have any issues to report...
+
+ if( nArgs < nArgsMandatoryCnt )
+ {
+ SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED ), nArgsMandatoryCnt ) );
+ return MIstatus::failure;
+ }
+
+ if( IsArgsPresentButNotHandledByCmd() )
+ WarningArgsNotHandledbyCmdLogFile( vStrMiCmd );
+
+ return ValidationFormErrorMessages( vwCmdArgsText );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Having validated the command's options text and failed for some reason form
+// the error message made up with the faults found.
+// Type: Method.
+// vCmdArgsText - (RW) A command's options or argument.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgSet::ValidationFormErrorMessages( const CMICmdArgContext & vwCmdArgsText )
+{
+ CMIUtilString strListMissing;
+ CMIUtilString strListInvalid;
+ CMIUtilString strListMissingInfo;
+ const bool bArgsMissing = (m_setCmdArgsThatAreMissing.size() > 0);
+ const bool bArgsInvalid = (m_setCmdArgsThatNotValid.size() > 0);
+ const bool bArgsMissingInfo = (m_setCmdArgsMissingInfo.size() > 0);
+ if( !(bArgsMissing || bArgsInvalid || bArgsMissingInfo) )
+ return MIstatus::success;
+ if( bArgsMissing )
+ {
+ MIuint i = 0;
+ SetCmdArgs_t::const_iterator it = m_setCmdArgsThatAreMissing.begin();
+ while( it != m_setCmdArgsThatAreMissing.end() )
+ {
+ if( i++ > 0 )
+ strListMissing += m_constStrCommaSpc;
+
+ const CMICmdArgValBase * pArg( *it );
+ strListMissing += pArg->GetName();
+
+ // Next
+ ++it;
+ }
+ }
+ if( bArgsInvalid )
+ {
+ MIuint i = 0;
+ SetCmdArgs_t::const_iterator it = m_setCmdArgsThatNotValid.begin();
+ while( it != m_setCmdArgsThatNotValid.end() )
+ {
+ if( i++ > 0 )
+ strListMissing += m_constStrCommaSpc;
+
+ const CMICmdArgValBase * pArg( *it );
+ strListInvalid += pArg->GetName();
+
+ // Next
+ ++it;
+ }
+ }
+ if( bArgsMissingInfo )
+ {
+ MIuint i = 0;
+ SetCmdArgs_t::const_iterator it = m_setCmdArgsMissingInfo.begin();
+ while( it != m_setCmdArgsMissingInfo.end() )
+ {
+ if( i++ > 0 )
+ strListMissingInfo += m_constStrCommaSpc;
+
+ const CMICmdArgValBase * pArg( *it );
+ strListMissingInfo += pArg->GetName();
+
+ // Next
+ ++it;
+ }
+ }
+
+ bool bHaveOneError = false;
+ CMIUtilString strError = MIRSRC( IDS_CMD_ARGS_ERR_PREFIX_MSG );
+ if( bArgsMissing && bArgsInvalid )
+ {
+ bHaveOneError = true;
+ strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID ), strListMissing.c_str(), strListInvalid.c_str() );
+ }
+ if( bArgsMissing )
+ {
+ if( bHaveOneError )
+ strError += ". ";
+ bHaveOneError = true;
+ strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY ), strListMissing.c_str() );
+ }
+ if( bArgsMissingInfo )
+ {
+ if( bHaveOneError )
+ strError += ". ";
+ bHaveOneError = true;
+ strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF ), strListMissingInfo.c_str() );
+ }
+ if( bArgsInvalid )
+ {
+ if( bHaveOneError )
+ strError += ". ";
+ bHaveOneError = true;
+ strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), strListInvalid.c_str() );
+ }
+ if( !vwCmdArgsText.IsEmpty() )
+ {
+ if( bHaveOneError )
+ strError += ". ";
+ bHaveOneError = true;
+ strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN ), vwCmdArgsText.GetArgsLeftToParse().c_str() );
+ }
+
+ if( bHaveOneError )
+ {
+ SetErrorDescription( strError );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Ask if the command's argument options text had any arguments.
+// Type: Method.
+// Args: None.
+// Return: bool - True = Has one or more arguments present, false = no arguments.
+// Throws: None.
+//--
+bool CMICmdArgSet::IsArgContextEmpty( void ) const
+{
+ return m_cmdArgContext.IsEmpty();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the number of arguments that are being used for the command.
+// Type: Method.
+// Args: None.
+// Return: MIuint - Argument count.
+// Throws: None.
+//--
+MIuint CMICmdArgSet::GetCount( void ) const
+{
+ return m_setCmdArgs.size();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Given a set of command argument objects retrieve the argument with the
+// specified name.
+// Type: Method.
+// Args: vpArg - (W) A pointer to a command's argument object.
+// Return: True - Argument found.
+// False - Argument not found.
+// Throws: None.
+//--
+bool CMICmdArgSet::GetArg( const CMIUtilString & vArgName, CMICmdArgValBase *& vpArg ) const
+{
+ bool bFound = false;
+ SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
+ while( it != m_setCmdArgs.end() )
+ {
+ CMICmdArgValBase * pArg( *it );
+ if( pArg->GetName() == vArgName )
+ {
+ bFound = true;
+ vpArg = pArg;
+ break;
+ }
+
+ // Next
+ ++it;
+ }
+
+ return bFound;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Write a warning message to the MI Log file about the command's arguments or
+// options that were found present but not handled.
+// Type: Method.
+// Args: vrCmdName - (R) The command's name.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdArgSet::WarningArgsNotHandledbyCmdLogFile( const CMIUtilString & vrCmdName )
+{
+#if MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
+
+ CMIUtilString strArgsNotHandled;
+ const CMICmdArgSet::SetCmdArgs_t & rSetArgs = GetArgsNotHandledByCmd();
+ MIuint nCnt = 0;
+ CMICmdArgSet::SetCmdArgs_t::const_iterator it = rSetArgs.begin();
+ while( it != rSetArgs.end() )
+ {
+ if( nCnt++ > 0 )
+ strArgsNotHandled += m_constStrCommaSpc;
+ const CMICmdArgValBase * pArg = *it;
+ strArgsNotHandled += pArg->GetName();
+
+ // Next
+ ++it;
+ }
+
+ const CMIUtilString strWarningMsg( CMIUtilString::Format( MIRSRC( IDS_CMD_WRN_ARGS_NOT_HANDLED ), vrCmdName.c_str(), strArgsNotHandled.c_str() ) );
+ m_pLog->WriteLog( strWarningMsg );
+
+#endif // MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
+}
diff --git a/tools/lldb-mi/MICmdArgSet.h b/tools/lldb-mi/MICmdArgSet.h
new file mode 100644
index 000000000000..5f8f5049d9af
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgSet.h
@@ -0,0 +1,109 @@
+//===-- MICmdArgSet.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgSet.h
+//
+// Overview: CMICmdArgSet interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <vector>
+
+// In-house headers:
+#include "MICmnBase.h"
+#include "MICmdArgContext.h"
+
+// Declarations:
+class CMICmdArgValBase;
+
+//++ ============================================================================
+// Details: MI common code class. Command arguments container class.
+// A command may have one or more arguments of which some may be optional.
+// *this class contains a list of the command's arguments which are
+// validates against the commands argument options string (context string).
+// Each argument tries to extract the value it is looking for.
+// Argument objects added to *this container are owned by this container
+// and are deleted when this container goes out of scope. Allocate argument
+// objects on the heap.
+// It is assummed the arguments to be parsed are read from left to right in
+// order. The order added to *this container is the order they will parsed.
+// Gotchas: None.
+// Authors: Illya Rudkin 14/04/2014.
+// Changes: None.
+//--
+class CMICmdArgSet : public CMICmnBase
+{
+// Classes:
+public:
+ //++
+ // Description: ArgSet's interface for command arguments to implement.
+ //--
+ class IArg
+ {
+ public:
+ virtual bool GetFound( void ) const = 0;
+ virtual bool GetIsHandledByCmd( void ) const = 0;
+ virtual bool GetIsMandatory( void ) const = 0;
+ virtual bool GetIsMissingOptions( void ) const = 0;
+ virtual const CMIUtilString & GetName( void ) const = 0;
+ virtual bool GetValid( void ) const = 0;
+ virtual bool Validate( CMICmdArgContext & vwArgContext ) = 0;
+
+ /* dtor */ virtual ~IArg( void ) {};
+ };
+
+// Typedefs:
+public:
+ typedef std::vector< CMICmdArgValBase * > SetCmdArgs_t;
+
+// Methods:
+public:
+ /* ctor */ CMICmdArgSet( void );
+
+ bool Add( const CMICmdArgValBase & vArg );
+ bool GetArg( const CMIUtilString & vArgName, CMICmdArgValBase *& vpArg ) const;
+ const SetCmdArgs_t & GetArgsThatAreMissing( void ) const;
+ const SetCmdArgs_t & GetArgsThatInvalid( void ) const;
+ MIuint GetCount( void ) const;
+ bool IsArgContextEmpty( void ) const;
+ bool IsArgsPresentButNotHandledByCmd( void ) const;
+ void WarningArgsNotHandledbyCmdLogFile( const CMIUtilString & vrCmdName );
+ bool Validate( const CMIUtilString & vStrMiCmd, CMICmdArgContext & vwCmdArgsText );
+
+// Overrideable:
+public:
+ /* dtor */ virtual ~CMICmdArgSet( void );
+
+// Methods:
+private:
+ const SetCmdArgs_t & GetArgsNotHandledByCmd( void ) const;
+ void Destroy( void ); // Release resources used by *this object
+ bool ValidationFormErrorMessages( const CMICmdArgContext & vwCmdArgsText );
+
+// Attributes:
+private:
+ bool m_bIsArgsPresentButNotHandledByCmd; // True = The driver's client presented the command with options recognised but not handled by a command, false = all args handled
+ SetCmdArgs_t m_setCmdArgs; // The set of arguments that are that the command is expecting to find in the options string
+ SetCmdArgs_t m_setCmdArgsThatAreMissing; // The set of arguments that are required by the command but are missing
+ SetCmdArgs_t m_setCmdArgsThatNotValid; // The set of arguments found in the text but for some reason unable to extract a value
+ SetCmdArgs_t m_setCmdArgsNotHandledByCmd; // The set of arguments specified by the command which were present to the command but not handled
+ SetCmdArgs_t m_setCmdArgsMissingInfo; // The set of arguments that were present but were found to be missing additional information i.e. --thread 3 but 3 is missing
+ CMICmdArgContext m_cmdArgContext; // Copy of the command's argument options text before validate takes place (empties it of content)
+ const CMIUtilString m_constStrCommaSpc;
+};
+
diff --git a/tools/lldb-mi/MICmdArgValBase.cpp b/tools/lldb-mi/MICmdArgValBase.cpp
new file mode 100644
index 000000000000..ceab1a494865
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValBase.cpp
@@ -0,0 +1,171 @@
+//===-- MICmdArgValBase.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValBase.cpp
+//
+// Overview: CMICmdArgValBase implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+#include "MIUtilString.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBase constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValBase::CMICmdArgValBase( void )
+: m_bFound( false )
+, m_bValid( false )
+, m_bMandatory( false )
+, m_bHandled( false )
+, m_bIsMissingOptions( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBase constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValBase::CMICmdArgValBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: m_bFound( false )
+, m_bValid( false )
+, m_bMandatory( vbMandatory )
+, m_strArgName( vrArgName )
+, m_bHandled( vbHandleByCmd )
+, m_bIsMissingOptions( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBase destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValBase::~CMICmdArgValBase( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag of whether the argument is handled by the command or
+// not.
+// Type: Method.
+// Args: None.
+// Return: True - Command needs more information.
+// False - All information is present as expected.
+// Throws: None.
+//--
+bool CMICmdArgValBase::GetIsMissingOptions( void ) const
+{
+ return m_bIsMissingOptions;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag of whether the argument is handled by the command or
+// not.
+// Type: Method.
+// Args: None.
+// Return: True - Command handles *this argument or option.
+// False - Not handled (argument specified but ignored).
+// Throws: None.
+//--
+bool CMICmdArgValBase::GetIsHandledByCmd( void ) const
+{
+ return m_bHandled;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the name of *this argument.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString & - Return the text name.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdArgValBase::GetName( void ) const
+{
+ return m_strArgName;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag of whether the argument was found in the command's
+// argument / options string.
+// Type: Method.
+// Args: None.
+// Return: True - Argument found.
+// False - Argument not found.
+// Throws: None.
+//--
+bool CMICmdArgValBase::GetFound( void ) const
+{
+ return m_bFound;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag indicating whether the value was obtained from the
+// text arguments string and is valid.
+// Type: Method.
+// Args: None.
+// Return: True - Argument valid.
+// False - Argument not valid.
+// Throws: None.
+//--
+bool CMICmdArgValBase::GetValid( void ) const
+{
+ return m_bValid;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the state flag indicating whether *this argument is a mandatory
+// argument for the command or is optional to be present.
+// Type: Method.
+// Args: None.
+// Return: True - Mandatory.
+// False - Optional.
+// Throws: None.
+//--
+bool CMICmdArgValBase::GetIsMandatory( void ) const
+{
+ return m_bMandatory;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overrideable.
+// Args: vArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValBase::Validate( CMICmdArgContext & vwArgContext )
+{
+ MIunused( vwArgContext );
+
+ // Override to implement
+
+ return MIstatus::failure;
+} \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdArgValBase.h b/tools/lldb-mi/MICmdArgValBase.h
new file mode 100644
index 000000000000..b367cb88ce29
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValBase.h
@@ -0,0 +1,157 @@
+//===-- Platform.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValBase.h
+//
+// Overview: CMICmdArgValBase interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MIUtilString.h"
+#include "MICmdArgSet.h"
+
+//++ ============================================================================
+// Details: MI common code class. Command argument base class. Arguments objects
+// needing specialization derived from *this class. An argument knows
+// what type of argument it is and how it is to interpret the options
+// (context) string to find and validate a matching argument and so
+// extract a value from it.
+// Argument objects are added to the CMICmdArgSet container object.
+// Once added the container they belong to that contain and will be
+// deleted when the container goes out of scope. Allocate argument
+// objects on the heap and pass in to the Add().
+// Note the code is written such that a command will produce an error
+// should it be presented with arguments or options it does not understand.
+// A command can recognise an option or argument then ignore if it
+// wishes (a warning is sent to the MI's Log file). This is so it is
+// hardwired to fail and catch arguments or options that presented by
+// different driver clients.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 14/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValBase : public CMICmdArgSet::IArg
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValBase( void );
+ /* ctor */ CMICmdArgValBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+
+// Overrideable:
+public:
+ /* dtor */ virtual ~CMICmdArgValBase( void );
+
+// Overridden:
+public:
+ // From CMICmdArgSet::IArg
+ virtual bool GetFound( void ) const;
+ virtual bool GetIsHandledByCmd( void ) const;
+ virtual bool GetIsMandatory( void ) const;
+ virtual bool GetIsMissingOptions( void ) const;
+ virtual const CMIUtilString & GetName( void ) const;
+ virtual bool GetValid( void ) const;
+ virtual bool Validate( CMICmdArgContext & vwArgContext );
+
+// Attributes:
+protected:
+ bool m_bFound; // True = yes found in arguments options text, false = not found
+ bool m_bValid; // True = yes argument parsed and valid, false = not valid
+ bool m_bMandatory; // True = yes arg must be present, false = optional argument
+ CMIUtilString m_strArgName;
+ bool m_bHandled; // True = Command processes *this option, false = not handled
+ bool m_bIsMissingOptions; // True = Command needs more information, false = ok
+};
+
+//++ ============================================================================
+// Details: MI common code class. Templated command argument base class.
+// Gotchas: None.
+// Authors: Illya Rudkin 14/04/2014.
+// Changes: None.
+//--
+template< class T >
+class CMICmdArgValBaseTemplate : public CMICmdArgValBase
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValBaseTemplate( void );
+ /* ctor */ CMICmdArgValBaseTemplate( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ //
+ const T & GetValue( void ) const;
+
+// Overrideable:
+public:
+ /* dtor */ virtual ~CMICmdArgValBaseTemplate( void );
+
+// Attributes:
+protected:
+ T m_argValue;
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBaseTemplate constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+template< class T >
+CMICmdArgValBaseTemplate< T >::CMICmdArgValBaseTemplate( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBaseTemplate constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+template< class T >
+CMICmdArgValBaseTemplate< T >::CMICmdArgValBaseTemplate( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValBase( vrArgName, vbMandatory, vbHandleByCmd )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValBaseTemplate destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+template< class T >
+CMICmdArgValBaseTemplate< T >::~CMICmdArgValBaseTemplate( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the value the argument parsed from the command's argument / options
+// text string.
+// Type: Method.
+// Args: None.
+// Return: Template type & - The arg value of *this object.
+// Throws: None.
+//--
+template< class T >
+const T & CMICmdArgValBaseTemplate< T >::GetValue( void ) const
+{
+ return m_argValue;
+}
diff --git a/tools/lldb-mi/MICmdArgValConsume.cpp b/tools/lldb-mi/MICmdArgValConsume.cpp
new file mode 100644
index 000000000000..72a57f870ad4
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValConsume.cpp
@@ -0,0 +1,119 @@
+//===-- MICmdArgValConsume.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValConsume.cpp
+//
+// Overview: CMICmdArgValConsume implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValConsume.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValConsume constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValConsume::CMICmdArgValConsume( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValConsume constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValConsume::CMICmdArgValConsume( const CMIUtilString & vrArgName, const bool vbMandatory )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, true )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValConsume destructor.
+// Type: Overidden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValConsume::~CMICmdArgValConsume( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (R) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValConsume::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ if( vwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
+ m_bFound = true;
+ m_bValid = true;
+ vwArgContext.RemoveArg( rArg );
+ return MIstatus::success;
+ }
+
+ // In reality there are more than one option, if so the file option
+ // is the last one (don't handle that here - find the best looking one)
+ const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rTxt( *it );
+ m_bFound = true;
+
+ if( vwArgContext.RemoveArg( rTxt ) )
+ {
+ m_bValid = true;
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::success;
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Nothing to examine as we just want to consume the argument or option (ignore
+// it).
+// Type: Method.
+// Args: None.
+// Return: bool - True = yes ok, false = not ok.
+// Throws: None.
+//--
+bool CMICmdArgValConsume::IsOk( void ) const
+{
+ return true;
+}
diff --git a/tools/lldb-mi/MICmdArgValConsume.h b/tools/lldb-mi/MICmdArgValConsume.h
new file mode 100644
index 000000000000..a113d89458f3
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValConsume.h
@@ -0,0 +1,63 @@
+//===-- MICmdArgValConsume.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValConsume.h
+//
+// Overview: CMICmdArgValConsume interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument. This type having recognised its argument name just consumes
+// that argument or option (ignores it). This is the so the validation
+// process can then ask if all arguments or options have been recognised
+// other an error will occurred "argument not recognised". For example
+// this can be used to consume the "--" text which is not an argument in
+// itself. Normally the GetValue() function (in base class) would return
+// a value for the argument but is not the case for *this argument type
+// object.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 20/05/2014.
+// Changes: None.
+//--
+class CMICmdArgValConsume : public CMICmdArgValBaseTemplate< CMIUtilString >
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValConsume( void );
+ /* ctor */ CMICmdArgValConsume( const CMIUtilString & vrArgName, const bool vbMandatory );
+ //
+ bool IsOk( void ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValConsume( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vwArgContext );
+};
diff --git a/tools/lldb-mi/MICmdArgValFile.cpp b/tools/lldb-mi/MICmdArgValFile.cpp
new file mode 100644
index 000000000000..d5cc52b90b44
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValFile.cpp
@@ -0,0 +1,204 @@
+//===-- MICmdArgValFile.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValFile.cpp
+//
+// Overview: CMICmdArgValFile implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValFile.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValFile constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValFile::CMICmdArgValFile( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValFile constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValFile::CMICmdArgValFile( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValFile destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValFile::~CMICmdArgValFile( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (R) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValFile::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ // The GDB/MI spec suggests there is only parameter
+
+ if( vwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rFile( vwArgContext.GetArgsLeftToParse() );
+ if( IsFilePath( rFile ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = rFile.Trim( '"' );
+ vwArgContext.RemoveArg( rFile );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // In reality there are more than one option, if so the file option
+ // is the last one (don't handle that here - find the best looking one)
+ const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rTxt( *it );
+ if( IsFilePath( rTxt ) )
+ {
+ m_bFound = true;
+
+ if( vwArgContext.RemoveArg( rTxt ) )
+ {
+ m_bValid = true;
+ m_argValue = rTxt.Trim( '"' );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::success;
+ }
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Given some text extract the file name path from it. If a space is found in
+// path done return the path surrounded in quotes.
+// Type: Method.
+// Args: vrTxt - (R) The text to extract the file name path from.
+// Return: CMIUtilString - File name and or path.
+// Throws: None.
+//--
+CMIUtilString CMICmdArgValFile::GetFileNamePath( const CMIUtilString & vrTxt ) const
+{
+ CMIUtilString fileNamePath( vrTxt );
+
+ // Look for a space in the path
+ const MIchar cSpace = ' ';
+ const MIint nPos = fileNamePath.find( cSpace );
+ if( nPos != (MIint) std::string::npos )
+ fileNamePath = CMIUtilString::Format( "\"%s\"", fileNamePath.c_str() );
+
+ return fileNamePath;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid file name path.
+// Type: Method.
+// Args: vrFileNamePath - (R) File's name and directory path.
+// Return: bool - True = yes valid file path, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValFile::IsFilePath( const CMIUtilString & vrFileNamePath ) const
+{
+ if( vrFileNamePath.empty() )
+ return false;
+
+ const bool bHavePosSlash = (vrFileNamePath.find_first_of( "/" ) != std::string::npos);
+ const bool bHaveBckSlash = (vrFileNamePath.find_first_of( "\\" ) != std::string::npos);
+
+ // Look for --someLongOption
+ MIint nPos = vrFileNamePath.find_first_of( "--" );
+ const bool bLong = (nPos == 0);
+ if( bLong )
+ return false;
+
+ // Look for -f type short parameters
+ nPos = vrFileNamePath.find_first_of( "-" );
+ const bool bShort = (nPos == 0);
+ if( bShort )
+ return false;
+
+ // Look for i1 i2 i3....
+ nPos = vrFileNamePath.find_first_of( "i" );
+ const bool bFoundI1 = ((nPos == 0) && (::isdigit( vrFileNamePath[ 1 ] )) );
+ if( bFoundI1 )
+ return false;
+
+ const bool bValidChars = IsValidChars( vrFileNamePath );
+ if( bValidChars || bHavePosSlash || bHaveBckSlash )
+ return true;
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Determine if the path contains valid characters for a file path. Letters can be
+// either upper or lower case.
+// Type: Method.
+// Args: vrText - (R) The text data to examine.
+// Return: bool - True = yes valid, false = one or more chars is valid.
+// Throws: None.
+//--
+bool CMICmdArgValFile::IsValidChars( const CMIUtilString & vrText ) const
+{
+ const MIchar * pPtr = const_cast< MIchar * >( vrText.c_str() );
+ for( MIuint i = 0; i < vrText.length(); i++, pPtr++ )
+ {
+ const MIchar c = *pPtr;
+ if( ::isalnum( (int) c ) == 0 )
+ {
+ if( (c != '.') && (c != '-') && (c != '_') )
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/tools/lldb-mi/MICmdArgValFile.h b/tools/lldb-mi/MICmdArgValFile.h
new file mode 100644
index 000000000000..071727401454
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValFile.h
@@ -0,0 +1,61 @@
+//===-- MICmdArgValFile.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValFile.h
+//
+// Overview: CMICmdArgValFile interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it .
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 15/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValFile : public CMICmdArgValBaseTemplate< CMIUtilString >
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValFile( void );
+ /* ctor */ CMICmdArgValFile( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ //
+ bool IsFilePath( const CMIUtilString & vrFileNamePath ) const;
+ CMIUtilString GetFileNamePath( const CMIUtilString & vrTxt ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValFile( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vwArgContext );
+
+// Methods:
+private:
+ bool IsValidChars( const CMIUtilString & vrText ) const;
+};
diff --git a/tools/lldb-mi/MICmdArgValListBase.cpp b/tools/lldb-mi/MICmdArgValListBase.cpp
new file mode 100644
index 000000000000..37b729e42741
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValListBase.cpp
@@ -0,0 +1,221 @@
+//===-- MICmdArgValListBase.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValListBase.cpp
+//
+// Overview: CMICmdArgValListBase implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValListBase.h"
+#include "MICmdArgContext.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValConsume.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListBase constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListBase::CMICmdArgValListBase( void )
+: m_eArgType( eArgValType_invalid )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListBase constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListBase::CMICmdArgValListBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+, m_eArgType( eArgValType_invalid )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListBase constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// veType - (R) The type of argument to look for and create argument object of a certain type.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListBase::CMICmdArgValListBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+, m_eArgType( veType )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListBase destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListBase::~CMICmdArgValListBase( void )
+{
+ // Tidy up
+ Destroy();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Tear down resources used by *this object.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdArgValListBase::Destroy( void )
+{
+ // Tidy up
+ VecArgObjPtr_t::const_iterator it = m_argValue.begin();
+ while( it != m_argValue.end() )
+ {
+ CMICmdArgValBase * pArgObj = *it;
+ delete pArgObj;
+
+ // Next
+ ++it;
+ }
+ m_argValue.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Create an CMICmdArgValBase derived object matching the type specified
+// and put the option or argument's value inside it.
+// Type: Method.
+// Args: vrTxt - (R) Text version the option or argument.
+// veType - (R) The type of argument or option object to create.
+// Return: CMICmdArgValBase * - Option object holding the value.
+// - NULL = Functional failed.
+// Throws: None.
+//--
+CMICmdArgValBase * CMICmdArgValListBase::CreationObj( const CMIUtilString & vrTxt, const ArgValType_e veType ) const
+{
+ CMICmdArgValBase * pOptionObj = nullptr;
+ switch( veType )
+ {
+ case eArgValType_File:
+ pOptionObj = new CMICmdArgValFile();
+ break;
+ case eArgValType_Consume:
+ pOptionObj = new CMICmdArgValConsume();
+ break;
+ case eArgValType_Number:
+ pOptionObj = new CMICmdArgValNumber();
+ break;
+ case eArgValType_OptionLong:
+ pOptionObj = new CMICmdArgValOptionLong();
+ break;
+ case eArgValType_OptionShort:
+ pOptionObj = new CMICmdArgValOptionShort();
+ break;
+ case eArgValType_String:
+ pOptionObj = new CMICmdArgValString();
+ break;
+ case eArgValType_StringQuoted:
+ pOptionObj = new CMICmdArgValString( true, false, false );
+ break;
+ case eArgValType_StringQuotedNumber:
+ pOptionObj = new CMICmdArgValString( true, true, false );
+ break;
+ case eArgValType_StringQuotedNumberPath:
+ pOptionObj = new CMICmdArgValString( true, true, true );
+ break;
+ case eArgValType_StringAnything:
+ pOptionObj = new CMICmdArgValString( true );
+ break;
+ case eArgValType_ThreadGrp:
+ pOptionObj = new CMICmdArgValThreadGrp();
+ break;
+ default:
+ return nullptr;
+ }
+
+ CMICmdArgContext argCntxt( vrTxt );
+ if( !pOptionObj->Validate( argCntxt ) )
+ return nullptr;
+
+ return pOptionObj;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Validate the option or argument is the correct type.
+// Type: Method.
+// Args: vrTxt - (R) Text version the option or argument.
+// veType - (R) The type of value to expect.
+// Return: bool - True = Yes expected type present, False = no.
+// Throws: None.
+//--
+bool CMICmdArgValListBase::IsExpectedCorrectType( const CMIUtilString & vrTxt, const ArgValType_e veType ) const
+{
+ bool bValid = false;
+ switch( veType )
+ {
+ case eArgValType_File:
+ bValid = CMICmdArgValFile().IsFilePath( vrTxt );
+ break;
+ case eArgValType_Consume:
+ bValid = CMICmdArgValConsume().IsOk();
+ break;
+ case eArgValType_Number:
+ bValid = CMICmdArgValNumber().IsArgNumber( vrTxt );
+ break;
+ case eArgValType_OptionLong:
+ bValid = CMICmdArgValOptionLong().IsArgLongOption( vrTxt );
+ break;
+ case eArgValType_OptionShort:
+ bValid = CMICmdArgValOptionShort().IsArgShortOption( vrTxt );
+ break;
+ case eArgValType_String:
+ bValid = CMICmdArgValString().IsStringArg( vrTxt );
+ break;
+ case eArgValType_StringQuoted:
+ bValid = CMICmdArgValString( true, false, false ).IsStringArg( vrTxt );
+ break;
+ case eArgValType_StringQuotedNumber:
+ bValid = CMICmdArgValString( true, true, false ).IsStringArg( vrTxt );
+ break;
+ case eArgValType_StringQuotedNumberPath:
+ bValid = CMICmdArgValString( true, true, true ).IsStringArg( vrTxt );
+ break;
+ case eArgValType_StringAnything:
+ bValid = CMICmdArgValString( true ).IsStringArg( vrTxt );
+ break;
+ case eArgValType_ThreadGrp:
+ bValid = CMICmdArgValThreadGrp().IsArgThreadGrp( vrTxt );
+ break;
+ default:
+ return false;
+ }
+
+ return bValid;
+}
diff --git a/tools/lldb-mi/MICmdArgValListBase.h b/tools/lldb-mi/MICmdArgValListBase.h
new file mode 100644
index 000000000000..2798efa19a48
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValListBase.h
@@ -0,0 +1,103 @@
+//===-- MICmdArgValListBase.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValListBase.h
+//
+// Overview: CMICmdArgValListBase interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <vector>
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument with addition options class.
+// For example --recurse 1 2 4 [group ...]. Arguments object that
+// require a list of options associated with them derive from the
+// CMICmdArgValListBase class. Additional options are also extracted from
+// the command arguments text string.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// options and so extract a values from it .
+// The CMICmdArgValBase objects are added to the derived argument class's
+// container. The option arguments belong to that derived class and will
+// be deleted that object goes out of scope.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 16/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValListBase : public CMICmdArgValBaseTemplate< std::vector< CMICmdArgValBase * > >
+{
+// Typedef:
+public:
+ typedef std::vector< CMICmdArgValBase * > VecArgObjPtr_t;
+
+// Enums:
+public:
+ //++ ---------------------------------------------------------------------------------
+ // Details: CMICmdArgValListBase needs to know what type of argument to look for in
+ // the command options text. It also needs to create argument objects of
+ // a specific type.
+ //--
+ enum ArgValType_e
+ {
+ eArgValType_File = 0,
+ eArgValType_Consume,
+ eArgValType_Number,
+ eArgValType_OptionLong,
+ eArgValType_OptionShort,
+ eArgValType_String,
+ eArgValType_StringQuoted,
+ eArgValType_StringQuotedNumber,
+ eArgValType_StringQuotedNumberPath,
+ eArgValType_StringAnything, // Accept any words for a string 'type' even if they look like --longOptions for example
+ eArgValType_ThreadGrp,
+ eArgValType_count, // Always the last one
+ eArgValType_invalid
+ };
+
+// Methods:
+public:
+ /* ctor */ CMICmdArgValListBase( void );
+ /* ctor */ CMICmdArgValListBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ /* ctor */ CMICmdArgValListBase( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType );
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValListBase( void );
+
+// Methods:
+protected:
+ bool IsExpectedCorrectType( const CMIUtilString & vrTxt, const ArgValType_e veType ) const;
+ CMICmdArgValBase * CreationObj( const CMIUtilString & vrTxt, const ArgValType_e veType ) const;
+
+// Attributes:
+protected:
+ ArgValType_e m_eArgType;
+
+// Methods:
+private:
+ void Destroy( void );
+};
diff --git a/tools/lldb-mi/MICmdArgValListOfN.cpp b/tools/lldb-mi/MICmdArgValListOfN.cpp
new file mode 100644
index 000000000000..246fa2c9445d
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValListOfN.cpp
@@ -0,0 +1,189 @@
+//===-- MICmdArgValListOfN.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValListOfN.cpp
+//
+// Overview: CMICmdArgValListOfN implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValListOfN.h"
+#include "MICmdArgContext.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListOfN constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListOfN::CMICmdArgValListOfN( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListOfN constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// veType - (R) The type of argument to look for and create argument object of a certain type.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListOfN::CMICmdArgValListOfN( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType )
+: CMICmdArgValListBase( vrArgName, vbMandatory, vbHandleByCmd, veType )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValListOfN destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValListOfN::~CMICmdArgValListOfN( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the list of
+// arguments based on the argument object type to look for.
+// Type: Overridden.
+// Args: vwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValListOfN::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( m_eArgType >= eArgValType_count )
+ {
+ m_eArgType = eArgValType_invalid;
+ return MIstatus::failure;
+ }
+
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
+ if( IsListOfN( rArg ) && CreateList( rArg ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ vwArgContext.RemoveArg( rArg );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Create list of argument objects each holding a value extract from the command
+// options line.
+// Type: Method.
+// Args: vrTxt - (R) Some options text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValListOfN::CreateList( const CMIUtilString & vrTxt )
+{
+ CMIUtilString::VecString_t vecOptions;
+ if( (m_eArgType == eArgValType_StringQuoted) ||
+ (m_eArgType == eArgValType_StringQuotedNumber) ||
+ (m_eArgType == eArgValType_StringQuotedNumberPath) ||
+ (m_eArgType == eArgValType_StringAnything) )
+ {
+ if( vrTxt.SplitConsiderQuotes( " ", vecOptions ) == 0 )
+ return MIstatus::failure;
+ }
+ else
+ if( vrTxt.Split( " ", vecOptions ) == 0 )
+ return MIstatus::failure;
+
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rOption = *it;
+ CMICmdArgValBase * pOption = CreationObj( rOption, m_eArgType );
+ if( pOption != nullptr )
+ m_argValue.push_back( pOption );
+ else
+ return MIstatus::failure;
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValListOfN::IsListOfN( const CMIUtilString & vrTxt ) const
+{
+ CMIUtilString::VecString_t vecOptions;
+ if( (m_eArgType == eArgValType_StringQuoted) ||
+ (m_eArgType == eArgValType_StringQuotedNumber) ||
+ (m_eArgType == eArgValType_StringQuotedNumberPath) ||
+ (m_eArgType == eArgValType_StringAnything) )
+ {
+ if( vrTxt.SplitConsiderQuotes( " ", vecOptions ) == 0 )
+ return false;
+ }
+ else
+ if( vrTxt.Split( " ", vecOptions ) == 0 )
+ return false;
+
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rOption = *it;
+ if( !IsExpectedCorrectType( rOption, m_eArgType ) )
+ break;
+
+ // Next
+ ++it;
+ }
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the list of CMICmdArgValBase derived option objects found following
+// *this long option argument. For example "list-thread-groups [ --recurse 1 ]"
+// where 1 is the list of expected option to follow.
+// Type: Method.
+// Args: None.
+// Return: CMICmdArgValListBase::VecArgObjPtr_t & - List of options.
+// Throws: None.
+//--
+const CMICmdArgValListBase::VecArgObjPtr_t & CMICmdArgValListOfN::GetExpectedOptions( void ) const
+{
+ return m_argValue;
+}
diff --git a/tools/lldb-mi/MICmdArgValListOfN.h b/tools/lldb-mi/MICmdArgValListOfN.h
new file mode 100644
index 000000000000..0fe5d2f4f831
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValListOfN.h
@@ -0,0 +1,98 @@
+//===-- MICmdArgValListOfN.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValListOfN.h
+//
+// Overview: CMICmdArgValListOfN interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <vector>
+
+// In-house headers:
+#include "MICmdArgValListBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it .
+// The CMICmdArgValBase objects added to *this ListOfN container belong
+// to this container and will be deleted when *this object goes out of
+// scope.
+// To parse arguments like 'thread-id ...' i.e. 1 10 12 13 ...
+// If vbMandatory argument is true it takes on the (...)+ specification
+// otherwise assumed to be (...)* specification.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 16/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValListOfN : public CMICmdArgValListBase
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValListOfN( void );
+ /* ctor */ CMICmdArgValListOfN( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType );
+ //
+ const VecArgObjPtr_t & GetExpectedOptions( void ) const;
+ template< class T1, typename T2 >
+ bool GetExpectedOption( T2 & vrwValue ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValListOfN( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vArgContext );
+
+// Methods:
+private:
+ bool IsListOfN( const CMIUtilString & vrTxt ) const;
+ bool CreateList( const CMIUtilString & vrTxt );
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the first argument or option value from the list of 1 or more options
+// parsed from the command's options string.
+// Type: Template method.
+// Args: vrwValue - (W) Templated type return value.
+// T1 - The argument value's class type of the data hold in the list of options.
+// T2 - The type pf the variable which holds the value wanted.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed. List of object was empty.
+// Throws: None.
+//--
+template< class T1, typename T2 >
+bool CMICmdArgValListOfN::GetExpectedOption( T2 & vrwValue ) const
+{
+ const VecArgObjPtr_t & rVecOptions( GetExpectedOptions() );
+ VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin();
+ if( it2 != rVecOptions.end() )
+ {
+ const T1 * pOption = static_cast< T1 * >( *it2 );
+ vrwValue = pOption->GetValue();
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
diff --git a/tools/lldb-mi/MICmdArgValNumber.cpp b/tools/lldb-mi/MICmdArgValNumber.cpp
new file mode 100644
index 000000000000..18bdccdc9ac5
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValNumber.cpp
@@ -0,0 +1,167 @@
+//===-- MICmdArgValNumber.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValNumber.cpp
+//
+// Overview: CMICmdArgValNumber implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValNumber.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValNumber constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValNumber::CMICmdArgValNumber( void )
+: m_nNumber( 0 )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValNumber constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValNumber::CMICmdArgValNumber( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+, m_nNumber( 0 )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValNumber destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValNumber::~CMICmdArgValNumber( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValNumber::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ if( vwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
+ if( IsArgNumber( rArg ) && ExtractNumber( rArg ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = GetNumber();
+ vwArgContext.RemoveArg( rArg );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // More than one option...
+ const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rArg( *it );
+ if( IsArgNumber( rArg ) && ExtractNumber( rArg ) )
+ {
+ m_bFound = true;
+
+ if( vwArgContext.RemoveArg( rArg ) )
+ {
+ m_bValid = true;
+ m_argValue = GetNumber();
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValNumber::IsArgNumber( const CMIUtilString & vrTxt ) const
+{
+ // Look for --someLongOption
+ if( std::string::npos != vrTxt.find( "--" ) )
+ return false;
+
+ return vrTxt.IsNumber();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Extract the thread group number from the thread group argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValNumber::ExtractNumber( const CMIUtilString & vrTxt )
+{
+ MIint64 nNumber = 0;
+ bool bOk = vrTxt.ExtractNumber( nNumber );
+ if( bOk )
+ {
+ m_nNumber = static_cast< MIint >( nNumber );
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the thread group ID found in the argument.
+// Type: Method.
+// Args: None.
+// Return: MIuint - Thread group ID.
+// Throws: None.
+//--
+MIint64 CMICmdArgValNumber::GetNumber( void ) const
+{
+ return m_nNumber;
+}
+
diff --git a/tools/lldb-mi/MICmdArgValNumber.h b/tools/lldb-mi/MICmdArgValNumber.h
new file mode 100644
index 000000000000..219b040a257d
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValNumber.h
@@ -0,0 +1,65 @@
+//===-- MICmdArgValNumber.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValNumber.h
+//
+// Overview: CMICmdArgValNumber interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it .
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 14/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValNumber : public CMICmdArgValBaseTemplate< MIint64 >
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValNumber( void );
+ /* ctor */ CMICmdArgValNumber( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ //
+ bool IsArgNumber( const CMIUtilString & vrTxt ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValNumber( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vwArgContext );
+
+// Methods:
+private:
+ bool ExtractNumber( const CMIUtilString & vrTxt );
+ MIint64 GetNumber( void ) const;
+
+// Attributes:
+private:
+ MIint64 m_nNumber;
+};
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.cpp b/tools/lldb-mi/MICmdArgValOptionLong.cpp
new file mode 100644
index 000000000000..6c87984ba811
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValOptionLong.cpp
@@ -0,0 +1,319 @@
+//===-- MICmdArgValOptionLong.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValOptionLong.cpp
+//
+// Overview: CMICmdArgValOptionLong implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionLong constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionLong::CMICmdArgValOptionLong( void )
+: m_nExpectingNOptions( 0 )
+, m_eExpectingOptionType( eArgValType_invalid )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionLong constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionLong::CMICmdArgValOptionLong( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValListBase( vrArgName, vbMandatory, vbHandleByCmd )
+, m_nExpectingNOptions( 0 )
+, m_eExpectingOptionType( eArgValType_invalid )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionLong constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// veType - (R) The type of argument to look for and create argument object of a certain type.
+// vnExpectingNOptions - (R) The number of options expected to read following *this argument.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionLong::CMICmdArgValOptionLong( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType, const MIuint vnExpectingNOptions )
+: CMICmdArgValListBase( vrArgName, vbMandatory, vbHandleByCmd )
+, m_nExpectingNOptions( vnExpectingNOptions )
+, m_eExpectingOptionType( veType )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionLong destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionLong::~CMICmdArgValOptionLong( void )
+{
+ // Tidy up
+ Destroy();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Tear down resources used by *this object.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdArgValOptionLong::Destroy( void )
+{
+ // Tidy up
+ VecArgObjPtr_t::const_iterator it = m_vecArgsExpected.begin();
+ while( it != m_vecArgsExpected.end() )
+ {
+ CMICmdArgValBase * pOptionObj = *it;
+ delete pOptionObj;
+
+ // Next
+ ++it;
+ }
+ m_vecArgsExpected.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the long
+// argument *this argument type is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValOptionLong::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ if( vwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
+ if( IsArgLongOption( rArg ) && ArgNameMatch( rArg ) )
+ {
+ m_bFound = true;
+
+ if( !vwArgContext.RemoveArg( rArg ) )
+ return MIstatus::failure;
+
+ if( m_nExpectingNOptions == 0 )
+ {
+ m_bValid = true;
+ return MIstatus::success;
+ }
+
+ m_bIsMissingOptions = true;
+ return MIstatus::failure;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // More than one option...
+ MIuint nArgIndex = 0;
+ const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rArg( *it );
+ if( IsArgOptionCorrect( rArg ) && ArgNameMatch( rArg ) )
+ {
+ m_bFound = true;
+
+ if( !vwArgContext.RemoveArg( rArg ) )
+ return MIstatus::failure;
+
+ if( m_nExpectingNOptions != 0 )
+ {
+ if( ExtractExpectedOptions( vwArgContext, nArgIndex ) )
+ {
+ m_bValid = true;
+ return MIstatus::success;
+ }
+
+ m_bIsMissingOptions = true;
+ return MIstatus::failure;
+ }
+ else
+ {
+ m_bValid = true;
+ return MIstatus::success;
+ }
+ }
+
+ // Next
+ ++it;
+ ++nArgIndex;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the text following *this argument and extract the options the values of
+// CMICmdArgValListBase::m_eArgType forming argument objects for each of those
+// options extracted.
+// Type: Method.
+// Args: vrwTxt - (RW) The command's argument options string.
+// nArgIndex - (R) The Nth arg position in argument context from the left.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValOptionLong::ExtractExpectedOptions( CMICmdArgContext & vrwTxt, const MIuint nArgIndex )
+{
+ CMIUtilString::VecString_t vecOptions;
+ MIuint nOptionsPresent = 0;
+ if( (m_eExpectingOptionType != eArgValType_StringQuoted) &&
+ (m_eExpectingOptionType != eArgValType_StringQuotedNumber) &&
+ (m_eExpectingOptionType != eArgValType_StringQuotedNumberPath) )
+ nOptionsPresent = vrwTxt.GetArgsLeftToParse().Split( " ", vecOptions );
+ else
+ nOptionsPresent = vrwTxt.GetArgsLeftToParse().SplitConsiderQuotes( " ", vecOptions );
+ if( nOptionsPresent == 0 )
+ return MIstatus::failure;
+
+ MIuint nArgIndexCnt = 0;
+ MIuint nTypeCnt = 0;
+ MIuint nTypeCnt2 = 0;
+ MIuint nFoundNOptionsCnt = 0;
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ // Move to the Nth argument position from left before do validation/checking
+ if( nArgIndexCnt++ == nArgIndex )
+ {
+ nTypeCnt++;
+ const CMIUtilString & rOption( *it );
+ if( IsExpectedCorrectType( rOption, m_eExpectingOptionType ) )
+ {
+ nTypeCnt2++;
+ CMICmdArgValBase * pOptionObj = CreationObj( rOption, m_eExpectingOptionType );
+ if( (pOptionObj != nullptr) && vrwTxt.RemoveArgAtPos( rOption, nArgIndex ) )
+ {
+ nFoundNOptionsCnt++;
+ m_vecArgsExpected.push_back( pOptionObj );
+ }
+ }
+
+ // Is the sequence 'options' of same type broken. Expecting the same type until the
+ // next argument.
+ if( nTypeCnt != nTypeCnt2 )
+ return MIstatus::failure;
+
+ if( nFoundNOptionsCnt == m_nExpectingNOptions )
+ return MIstatus::success;
+ }
+
+ // Next
+ ++it;
+ }
+ if( nFoundNOptionsCnt != m_nExpectingNOptions )
+ return MIstatus::failure;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid long type option argument.
+// Long type argument looks like --someLongOption.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionLong::IsArgLongOption( const CMIUtilString & vrTxt ) const
+{
+ const bool bHavePosSlash = (vrTxt.find_first_of( "/" ) != std::string::npos);
+ const bool bHaveBckSlash = (vrTxt.find_first_of( "\\" ) != std::string::npos);
+ if( bHavePosSlash || bHaveBckSlash )
+ return false;
+
+ const MIint nPos = vrTxt.find_first_of( "--" );
+ if( nPos != 0 )
+ return false;
+
+ if( vrTxt.length() < 3 )
+ return false;
+
+ const CMIUtilString strArg = vrTxt.substr( 2 ).c_str();
+ if( strArg.IsNumber() )
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid long type option argument.
+// Long type argument looks like --someLongOption.
+// Type: Overideable.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionLong::IsArgOptionCorrect( const CMIUtilString & vrTxt ) const
+{
+ return IsArgLongOption( vrTxt );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Does the argument name of the argument being parsed ATM match the name of
+// *this argument object.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes arg name matched, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionLong::ArgNameMatch( const CMIUtilString & vrTxt ) const
+{
+ const CMIUtilString strArg = vrTxt.substr( 2 ).c_str();
+ return (strArg == GetName() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the list of CMICmdArgValBase derived option objects found following
+// *this long option argument. For example "list-thread-groups [ --recurse 1 ]"
+// where 1 is the list of expected option to follow.
+// Type: Method.
+// Args: None.
+// Return: CMICmdArgValListBase::VecArgObjPtr_t & - List of options.
+// Throws: None.
+//--
+const CMICmdArgValListBase::VecArgObjPtr_t & CMICmdArgValOptionLong::GetExpectedOptions( void ) const
+{
+ return m_vecArgsExpected;
+}
+
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.h b/tools/lldb-mi/MICmdArgValOptionLong.h
new file mode 100644
index 000000000000..3baae416c93a
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValOptionLong.h
@@ -0,0 +1,109 @@
+//===-- MICmdArgValOptionLong.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValOptionLong.h
+//
+// Overview: CMICmdArgValOptionLong interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValListBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+class CMIUtilString;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it.
+// If *this argument has expected options following it the option objects
+// created to hold each of those option's values belong to *this argument
+// object and so are deleted when *this object goes out of scope.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 16/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValOptionLong : public CMICmdArgValListBase
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValOptionLong( void );
+ /* ctor */ CMICmdArgValOptionLong( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ /* ctor */ CMICmdArgValOptionLong( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType, const MIuint vnExpectingNOptions );
+ //
+ bool IsArgLongOption( const CMIUtilString & vrTxt ) const;
+ const VecArgObjPtr_t & GetExpectedOptions( void ) const;
+ template< class T1, typename T2 >
+ bool GetExpectedOption( T2 & vrwValue ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValOptionLong( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vArgContext );
+
+// Methods:
+protected:
+ bool ExtractExpectedOptions( CMICmdArgContext & vrwTxt, const MIuint nArgIndex );
+
+// Overrideable:
+protected:
+ virtual bool IsArgOptionCorrect( const CMIUtilString & vrTxt ) const;
+ virtual bool ArgNameMatch( const CMIUtilString & vrTxt ) const;
+
+// Methods:
+private:
+ void Destroy( void );
+
+// Attributes:
+private:
+ MIuint m_nExpectingNOptions; // The number of options expected to read following *this argument
+ VecArgObjPtr_t m_vecArgsExpected; // The option objects holding the value extracted following *this argument
+ ArgValType_e m_eExpectingOptionType; // The type of options expected to read following *this argument
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the first argument or option value from the list of 1 or more options
+// parsed from the command's options string.
+// Type: Template method.
+// Args: vrwValue - (W) Templated type return value.
+// T1 - The argument value's class type of the data hold in the list of options.
+// T2 - The type pf the variable which holds the value wanted.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed. List of object was empty.
+// Throws: None.
+//--
+template< class T1, typename T2 >
+bool CMICmdArgValOptionLong::GetExpectedOption( T2 & vrwValue ) const
+{
+ const VecArgObjPtr_t & rVecOptions( GetExpectedOptions() );
+ VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin();
+ if( it2 != rVecOptions.end() )
+ {
+ const T1 * pOption = static_cast< T1 * >( *it2 );
+ vrwValue = pOption->GetValue();
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.cpp b/tools/lldb-mi/MICmdArgValOptionShort.cpp
new file mode 100644
index 000000000000..76adb7f11493
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValOptionShort.cpp
@@ -0,0 +1,128 @@
+//===-- MICmdArgValOptionShort.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValOptionShort.cpp
+//
+// Overview: CMICmdArgValOptionShort implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionShort constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionShort::CMICmdArgValOptionShort( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionShort constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionShort::CMICmdArgValOptionShort( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValOptionLong( vrArgName, vbMandatory, vbHandleByCmd )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionLong constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// veType - (R) The type of argument to look for and create argument object of a certain type.
+// vnExpectingNOptions - (R) The number of options expected to read following *this argument.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionShort::CMICmdArgValOptionShort( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType, const MIuint vnExpectingNOptions )
+: CMICmdArgValOptionLong( vrArgName, vbMandatory, vbHandleByCmd, veType, vnExpectingNOptions )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValOptionShort destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValOptionShort::~CMICmdArgValOptionShort( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid short type option argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionShort::IsArgShortOption( const CMIUtilString & vrTxt ) const
+{
+ // Look for --someLongOption
+ MIint nPos = vrTxt.find( "--" );
+ if( nPos == 0 )
+ return false;
+
+ // Look for -f short option
+ nPos = vrTxt.find( "-" );
+ if( nPos != 0 )
+ return false;
+
+ if( vrTxt.length() > 2 )
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid short type option argument.
+// Long type argument looks like -f some short option.
+// Type: Overridden.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionShort::IsArgOptionCorrect( const CMIUtilString & vrTxt ) const
+{
+ return IsArgShortOption( vrTxt );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Does the argument name of the argument being parsed ATM match the name of
+// *this argument object.
+// Type: Overridden.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes arg name matched, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValOptionShort::ArgNameMatch( const CMIUtilString & vrTxt ) const
+{
+ const CMIUtilString strArg = vrTxt.substr( 1 ).c_str();
+ return (strArg == GetName() );
+}
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.h b/tools/lldb-mi/MICmdArgValOptionShort.h
new file mode 100644
index 000000000000..7af038377123
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValOptionShort.h
@@ -0,0 +1,65 @@
+//===-- MICmdArgValOptionShort.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValOptionShort.h
+//
+// Overview: CMICmdArgValOptionShort interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValOptionLong.h"
+
+// Declarations:
+class CMICmdArgContext;
+class CMIUtilString;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValOptionLong class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it.
+// If *this argument has expected options following it the option objects
+// created to hold each of those option's values belong to *this argument
+// object and so are deleted when *this object goes out of scope.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 16/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValOptionShort : public CMICmdArgValOptionLong
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValOptionShort( void );
+ /* ctor */ CMICmdArgValOptionShort( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ /* ctor */ CMICmdArgValOptionShort( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const ArgValType_e veType, const MIuint vnExpectingNOptions );
+ //
+ bool IsArgShortOption( const CMIUtilString & vrTxt ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValOptionShort( void );
+
+// Overridden:
+private:
+ // From CMICmdArgValOptionLong
+ virtual bool IsArgOptionCorrect( const CMIUtilString & vrTxt ) const;
+ virtual bool ArgNameMatch( const CMIUtilString & vrTxt ) const;
+};
diff --git a/tools/lldb-mi/MICmdArgValString.cpp b/tools/lldb-mi/MICmdArgValString.cpp
new file mode 100644
index 000000000000..06818b1dc571
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValString.cpp
@@ -0,0 +1,502 @@
+//===-- MICmdArgValString.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValString.cpp
+//
+// Overview: CMICmdArgValString implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValString.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValString constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValString::CMICmdArgValString( void )
+: m_bHandleQuotedString( false )
+, m_bAcceptNumbers( false )
+, m_bHandleDirPaths( false )
+, m_bHandleAnything( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValString constructor.
+// Type: Method.
+// Args: vbAnything - (R) True = Parse a string and accept anything, false = do not accept anything.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValString::CMICmdArgValString( const bool vbAnything )
+: m_bHandleQuotedString( false )
+, m_bAcceptNumbers( false )
+, m_bHandleDirPaths( false )
+, m_bHandleAnything( vbAnything )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValString constructor.
+// Type: Method.
+// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character.
+// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as string types.
+// vbHandleDirPaths - (R) True = Parse a string and accept as a file path if a path, false = file paths are not recognised as string types.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValString::CMICmdArgValString( const bool vbHandleQuotes, const bool vbAcceptNumbers, const bool vbHandleDirPaths )
+: m_bHandleQuotedString( vbHandleQuotes )
+, m_bAcceptNumbers( vbAcceptNumbers )
+, m_bHandleDirPaths( vbHandleDirPaths )
+, m_bHandleAnything( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValString constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character. (Dflt = false)
+// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as string types. (Dflt = false)
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValString::CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes /* = false */, const bool vbAcceptNumbers /* = false */ )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+, m_bHandleQuotedString( vbHandleQuotes )
+, m_bAcceptNumbers( vbAcceptNumbers )
+, m_bHandleDirPaths( false )
+, m_bHandleAnything( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValString destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValString::~CMICmdArgValString( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vrwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValString::Validate( CMICmdArgContext & vrwArgContext )
+{
+ if( vrwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ if( m_bHandleQuotedString )
+ return (ValidateQuotedText( vrwArgContext ) || ValidateQuotedTextEmbedded( vrwArgContext ) );
+
+ return ValidateSingleText( vrwArgContext );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract only the next
+// word delimited by the next space.
+// Type: Method.
+// Args: vrwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValString::ValidateSingleText( CMICmdArgContext & vrwArgContext )
+{
+ if( vrwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rArg( vrwArgContext.GetArgsLeftToParse() );
+ if( IsStringArg( rArg ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = rArg;
+ vrwArgContext.RemoveArg( rArg );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // More than one option...
+ const CMIUtilString::VecString_t vecOptions( vrwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rArg( *it );
+ if( IsStringArg( rArg ) )
+ {
+ m_bFound = true;
+
+ if( vrwArgContext.RemoveArg( rArg ) )
+ {
+ m_bValid = true;
+ m_argValue = rArg;
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract all the words
+// between quotes then delimited by the next space. Can fall through to
+// ValidateSingleText() or ValidateQuotedQuotedTextEmbedded().
+// Type: Method.
+// Args: vrwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValString::ValidateQuotedText( CMICmdArgContext & vrwArgContext )
+{
+ // CODETAG_QUOTEDTEXT_SIMILAR_CODE
+ CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
+ const MIchar cQuote = '"';
+
+ // Look for first quote of two
+ MIint nPos = strOptions.find( cQuote );
+ if( nPos == (MIint) std::string::npos )
+ return ValidateSingleText( vrwArgContext );
+
+ // Is one and only quote at end of the string
+ const MIint nLen = strOptions.length();
+ if( nPos == (MIint)(nLen - 1) )
+ return MIstatus::failure;
+
+ // Quote must be the first character in the string or be preceeded by a space
+ if( (nPos > 0) && (strOptions[ nPos - 1 ] != ' ') )
+ return MIstatus::failure;
+
+ // Need to find the other quote
+ const MIint nPos2 = strOptions.rfind( cQuote );
+ if( nPos2 == (MIint) std::string::npos )
+ return MIstatus::failure;
+
+ // Is there quotes surrounding string formatting embedded quotes
+ if( IsStringArgQuotedQuotedTextEmbedded( strOptions ) )
+ return ValidateQuotedQuotedTextEmbedded( vrwArgContext );
+
+ // Make sure not same back quote, need two quotes
+ if( nPos == nPos2 )
+ return MIstatus::failure;
+
+ // Extract quoted text
+ const CMIUtilString strQuotedTxt = strOptions.substr( nPos, nPos2 - nPos + 1 ).c_str();
+ if( vrwArgContext.RemoveArg( strQuotedTxt ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = strOptions.substr( nPos + 1, nPos2 - nPos - 1 ).c_str();
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract all the words
+// between quotes then delimited by the next space. If there any string format
+// characters '\\' used to embed quotes these are ignored i.e. "\\\"%5d\\\""
+// becomes "%5d". Can fall through to ValidateQuotedText().
+// Type: Method.
+// Args: vrwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValString::ValidateQuotedTextEmbedded( CMICmdArgContext & vrwArgContext )
+{
+ // CODETAG_QUOTEDTEXT_SIMILAR_CODE
+ CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
+ const MIchar cBckSlash = '\\';
+ const MIint nPos = strOptions.find( cBckSlash );
+ if( nPos == (MIint) std::string::npos )
+ return ValidateQuotedText( vrwArgContext );
+
+ // Back slash must be the first character in the string or be preceeded by a space
+ // or '\\'
+ const MIchar cSpace = ' ';
+ if( (nPos > 0) && (strOptions[ nPos - 1 ] != cSpace) )
+ return MIstatus::failure;
+
+ // Need to find the other back slash
+ const MIint nPos2 = strOptions.rfind( cBckSlash );
+ if( nPos2 == (MIint) std::string::npos )
+ return MIstatus::failure;
+
+ // Make sure not same back slash, need two slashs
+ if( nPos == nPos2 )
+ return MIstatus::failure;
+
+ // Look for the two quotes
+ const MIint nLen = strOptions.length();
+ const MIchar cQuote = '"';
+ const MIint nPosQuote1 = nPos + 1;
+ const MIint nPosQuote2 = (nPos2 < nLen) ? nPos2 + 1 : nPos2;
+ if( (nPosQuote1 != nPosQuote2) &&
+ (strOptions[ nPosQuote1 ] != cQuote) && (strOptions[ nPosQuote2 ] != cQuote) )
+ return MIstatus::failure;
+
+ // Extract quoted text
+ const CMIUtilString strQuotedTxt = strOptions.substr( nPos, nPosQuote2 - nPos + 1 ).c_str();
+ if( vrwArgContext.RemoveArg( strQuotedTxt ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = strQuotedTxt;
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract all the words
+// between quotes then delimited by the next space. If there any string format
+// characters '\\' used to embed quotes these are ignored i.e. "\\\"%5d\\\""
+// becomes "%5d".
+// Type: Method.
+// Args: vrwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValString::ValidateQuotedQuotedTextEmbedded( CMICmdArgContext & vrwArgContext )
+{
+ // CODETAG_QUOTEDTEXT_SIMILAR_CODE
+ CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
+ const MIint nPos = strOptions.find( "\"\\\"" );
+ if( nPos == (MIint) std::string::npos )
+ return MIstatus::failure;
+
+ const MIint nPos2 = strOptions.rfind( "\\\"\"" );
+ if( nPos2 == (MIint) std::string::npos )
+ return MIstatus::failure;
+
+ const MIint nLen = strOptions.length();
+ if( (nLen > 5) && ((nPos + 2) == (nPos2 - 2)) )
+ return MIstatus::failure;
+
+ // Quote must be the first character in the string or be preceeded by a space
+ // or '\\'
+ const MIchar cSpace = ' ';
+ if( (nPos > 0) && (strOptions[ nPos - 1 ] != cSpace) )
+ return MIstatus::failure;
+
+ // Extract quoted text
+ const CMIUtilString strQuotedTxt = strOptions.substr( nPos, nPos2 - nPos + 3 ).c_str();
+ if( vrwArgContext.RemoveArg( strQuotedTxt ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = strQuotedTxt;
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValString::IsStringArg( const CMIUtilString & vrTxt ) const
+{
+ if( m_bHandleQuotedString )
+ return (IsStringArgQuotedText( vrTxt ) ||
+ IsStringArgQuotedTextEmbedded( vrTxt ) ||
+ IsStringArgQuotedQuotedTextEmbedded( vrTxt ) ||
+ IsStringArgSingleText( vrTxt ) ); // Still test for this as could just be one word still
+
+ return IsStringArgSingleText( vrTxt );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument or
+// option value. If the string looks like a long option, short option, a thread
+// group ID or just a number it is rejected as a string type value. There is an
+// option to allow the string to accept a number as a string type.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid argument value, false = something else.
+// Throws: None.
+//--
+bool CMICmdArgValString::IsStringArgSingleText( const CMIUtilString & vrTxt ) const
+{
+ // Accept anything as string word
+ if( m_bHandleAnything )
+ return true;
+
+ if( !m_bHandleDirPaths )
+ {
+ // Look for directory file paths, if found reject
+ const bool bHavePosSlash = (vrTxt.find_first_of( "/" ) != std::string::npos);
+ const bool bHaveBckSlash = (vrTxt.find_first_of( "\\" ) != std::string::npos);
+ if( bHavePosSlash || bHaveBckSlash )
+ return false;
+ }
+
+ // Look for --someLongOption, if found reject
+ if( 0 == vrTxt.find( "--" ) )
+ return false;
+
+ // Look for -f type short options, if found reject
+ if( (0 == vrTxt.find( "-" )) && (vrTxt.length() == 2) )
+ return false;
+
+ // Look for thread group i1 i2 i3...., if found reject
+ if( (vrTxt.find( "i" ) == 0) && ::isdigit( vrTxt[ 1 ]) )
+ return false;
+
+ // Look for numbers, if found reject
+ if( !m_bAcceptNumbers && vrTxt.IsNumber() )
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Take into account quotes surrounding the text. Note this function falls
+// through to IsStringArgSingleText() should the criteria match fail.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValString::IsStringArgQuotedText( const CMIUtilString & vrTxt ) const
+{
+ // CODETAG_QUOTEDTEXT_SIMILAR_CODE
+ const MIchar cQuote = '"';
+ const MIint nPos = vrTxt.find( cQuote );
+ if( nPos == (MIint) std::string::npos )
+ return false;
+
+ // Is one and only quote at end of the string
+ if( nPos == (MIint)(vrTxt.length() - 1) )
+ return false;
+
+ // Quote must be the first character in the string or be preceeded by a space
+ // Also check for embedded string formating quote
+ const MIchar cBckSlash = '\\';
+ const MIchar cSpace = ' ';
+ if( (nPos > 1) && (vrTxt[ nPos - 1 ] == cBckSlash) && (vrTxt[ nPos - 2 ] != cSpace) )
+ {
+ return false;
+ }
+ if( (nPos > 0) && (vrTxt[ nPos - 1 ] != cSpace) )
+ return false;
+
+ // Need to find the other quote
+ const MIint nPos2 = vrTxt.rfind( cQuote );
+ if( nPos2 == (MIint) std::string::npos )
+ return false;
+
+ // Make sure not same quote, need two quotes
+ if( nPos == nPos2 )
+ return MIstatus::failure;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Take into account quotes surrounding the text. Take into account string format
+// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this function falls
+// through to IsStringArgQuotedText() should the criteria match fail.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValString::IsStringArgQuotedTextEmbedded( const CMIUtilString & vrTxt ) const
+{
+ // CODETAG_QUOTEDTEXT_SIMILAR_CODE
+ const MIchar cBckSlash = '\\';
+ const MIint nPos = vrTxt.find( cBckSlash );
+ if( nPos == (MIint) std::string::npos )
+ return false;
+
+ // Slash must be the first character in the string or be preceeded by a space
+ const MIchar cSpace = ' ';
+ if( (nPos > 0) && (vrTxt[ nPos - 1 ] != cSpace) )
+ return false;
+
+ // Need to find the other matching slash
+ const MIint nPos2 = vrTxt.rfind( cBckSlash );
+ if( nPos2 == (MIint) std::string::npos )
+ return false;
+
+ // Make sure not same back slash, need two slashs
+ if( nPos == nPos2 )
+ return MIstatus::failure;
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Take into account quotes surrounding the text. Take into account string format
+// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this function falls
+// through to IsStringArgQuotedTextEmbedded() should the criteria match fail.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded( const CMIUtilString & vrTxt ) const
+{
+ const MIint nPos = vrTxt.find( "\"\\\"" );
+ if( nPos == (MIint) std::string::npos )
+ return false;
+
+ const MIint nPos2 = vrTxt.rfind( "\\\"\"" );
+ if( nPos2 == (MIint) std::string::npos )
+ return false;
+
+ const MIint nLen = vrTxt.length();
+ if( (nLen > 5) && ((nPos + 2) == (nPos2 - 2)) )
+ return false;
+
+ return true;
+}
diff --git a/tools/lldb-mi/MICmdArgValString.h b/tools/lldb-mi/MICmdArgValString.h
new file mode 100644
index 000000000000..ab411a02dc88
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValString.h
@@ -0,0 +1,76 @@
+//===-- MICmdArgValString.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValString.h
+//
+// Overview: CMICmdArgValString interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it .
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 15/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValString : public CMICmdArgValBaseTemplate< CMIUtilString >
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValString( void );
+ /* ctor */ CMICmdArgValString( const bool vbAnything );
+ /* ctor */ CMICmdArgValString( const bool vbHandleQuotes, const bool vbAcceptNumbers, const bool vbHandleDirPaths );
+ /* ctor */ CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes = false, const bool vbAcceptNumbers = false );
+ //
+ bool IsStringArg( const CMIUtilString & vrTxt ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValString( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vrwArgContext );
+
+// Methods:
+private:
+ bool ValidateSingleText( CMICmdArgContext & vrwArgContext );
+ bool ValidateQuotedText( CMICmdArgContext & vrwArgContext );
+ bool ValidateQuotedTextEmbedded( CMICmdArgContext & vrwArgContext );
+ bool ValidateQuotedQuotedTextEmbedded( CMICmdArgContext & vrwArgContext );
+ bool IsStringArgSingleText( const CMIUtilString & vrTxt ) const;
+ bool IsStringArgQuotedText( const CMIUtilString & vrTxt ) const;
+ bool IsStringArgQuotedTextEmbedded( const CMIUtilString & vrTxt ) const;
+ bool IsStringArgQuotedQuotedTextEmbedded( const CMIUtilString & vrTxt ) const;
+
+// Attribute:
+private:
+ bool m_bHandleQuotedString; // True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character
+ bool m_bAcceptNumbers; // True = Parse a string and accept as a number if number, false = numbers not recognised as string types
+ bool m_bHandleDirPaths; // True = Parse a string and accept directory file style string if present, false = directory file path not accepted
+ bool m_bHandleAnything; // True = Parse a string and accept anything if present, false = validate for criteria matches
+};
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.cpp b/tools/lldb-mi/MICmdArgValThreadGrp.cpp
new file mode 100644
index 000000000000..7d3290482119
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValThreadGrp.cpp
@@ -0,0 +1,173 @@
+//===-- MICmdArgValThreadGrp.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValThreadGrp.cpp
+//
+// Overview: CMICmdArgValThreadGrp implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValThreadGrp constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValThreadGrp::CMICmdArgValThreadGrp( void )
+: m_nThreadGrp( 0 )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValThreadGrp constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValThreadGrp::CMICmdArgValThreadGrp( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd )
+: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
+, m_nThreadGrp( 0 )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValThreadGrp destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValThreadGrp::~CMICmdArgValThreadGrp( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValThreadGrp::Validate( CMICmdArgContext & vwArgContext )
+{
+ if( vwArgContext.IsEmpty() )
+ return MIstatus::success;
+
+ if( vwArgContext.GetNumberArgsPresent() == 1 )
+ {
+ const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
+ if( IsArgThreadGrp( rArg ) && ExtractNumber( rArg ) )
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = GetNumber();
+ vwArgContext.RemoveArg( rArg );
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // More than one option...
+ const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
+ CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
+ while( it != vecOptions.end() )
+ {
+ const CMIUtilString & rArg( *it );
+ if( IsArgThreadGrp( rArg ) && ExtractNumber( rArg ) )
+ {
+ m_bFound = true;
+
+ if( vwArgContext.RemoveArg( rArg ) )
+ {
+ m_bValid = true;
+ m_argValue = GetNumber();
+ return MIstatus::success;
+ }
+ else
+ return MIstatus::failure;
+ }
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool CMICmdArgValThreadGrp::IsArgThreadGrp( const CMIUtilString & vrTxt ) const
+{
+ // Look for i1 i2 i3....
+ const MIint nPos = vrTxt.find_first_of( "i" );
+ if( nPos != 0 )
+ return false;
+
+ const CMIUtilString strNum = vrTxt.substr( 1 ).c_str();
+ if( !strNum.IsNumber() )
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Extract the thread group number from the thread group argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdArgValThreadGrp::ExtractNumber( const CMIUtilString & vrTxt )
+{
+ const CMIUtilString strNum = vrTxt.substr( 1 ).c_str();
+ MIint64 nNumber = 0;
+ bool bOk = strNum.ExtractNumber( nNumber );
+ if( bOk )
+ {
+ m_nThreadGrp = static_cast< MIuint >( nNumber );
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the thread group ID found in the argument.
+// Type: Method.
+// Args: None.
+// Return: MIuint - Thread group ID.
+// Throws: None.
+//--
+MIuint CMICmdArgValThreadGrp::GetNumber( void ) const
+{
+ return m_nThreadGrp;
+}
+
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.h b/tools/lldb-mi/MICmdArgValThreadGrp.h
new file mode 100644
index 000000000000..8903597dbca1
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValThreadGrp.h
@@ -0,0 +1,66 @@
+//===-- MICmdArgValThreadGrp.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdArgValThreadGrp.h
+//
+// Overview: CMICmdArgValThreadGrp interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it. Thread group looks like
+// "i1" in the options text.
+// Based on the Interpreter pattern.
+// Gotchas: None.
+// Authors: Illya Rudkin 15/04/2014.
+// Changes: None.
+//--
+class CMICmdArgValThreadGrp : public CMICmdArgValBaseTemplate< MIuint >
+{
+// Methods:
+public:
+ /* ctor */ CMICmdArgValThreadGrp( void );
+ /* ctor */ CMICmdArgValThreadGrp( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd );
+ //
+ bool IsArgThreadGrp( const CMIUtilString & vrTxt ) const;
+
+// Overridden:
+public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValThreadGrp( void );
+ // From CMICmdArgSet::IArg
+ virtual bool Validate( CMICmdArgContext & vArgContext );
+
+// Methods:
+private:
+ bool ExtractNumber( const CMIUtilString & vrTxt );
+ MIuint GetNumber( void ) const;
+
+// Attributes:
+private:
+ MIuint m_nThreadGrp;
+};
diff --git a/tools/lldb-mi/MICmdBase.cpp b/tools/lldb-mi/MICmdBase.cpp
new file mode 100644
index 000000000000..cedcba7e042f
--- /dev/null
+++ b/tools/lldb-mi/MICmdBase.cpp
@@ -0,0 +1,263 @@
+//===-- MICmdBase.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdBase.cpp
+//
+// Overview: CMICmdBase implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdBase constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdBase::CMICmdBase( void )
+: m_pSelfCreatorFn( nullptr )
+, m_rLLDBDebugSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() )
+, m_bHasResultRecordExtra( false )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdBase destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdBase::~CMICmdBase( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function.
+// Type: Overridden.
+// Args: None.
+// Return: SMICmdData & - *this command's present status/data/information.
+// Throws: None.
+//--
+const SMICmdData & CMICmdBase::GetCmdData( void ) const
+{
+ return m_cmdData;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - *this command's current error description.
+// Empty string indicates command status ok.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdBase::GetErrorDescription( void ) const
+{
+ return m_strCurrentErrDescription;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The CMICmdFactory requires this function. Retrieve the command and argument
+// options description string.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - Command decription.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdBase::GetMiCmd( void ) const
+{
+ return m_strMiCmd;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. A command must be given working data and
+// provide data about its status or provide information to other objects.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdBase::SetCmdData( const SMICmdData & vCmdData )
+{
+ m_cmdData = vCmdData;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The command factory requires this function. The factory calls this function
+// so it can obtain *this command's creation function.
+// Type: Overridden.
+// Args: None.
+// Return: CMICmdFactory::CmdCreatorFnPtr - Function pointer.
+// Throws: None.
+//--
+CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn( void ) const
+{
+ return m_pSelfCreatorFn;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: If a command is an event type (has callbacks registered with SBListener) it
+// needs to inform the Invoker that it has finished its work so that the
+// Invoker can tidy up and call the commands Acknowledge function (yes the
+// command itself could call the Acknowledge itself but not doing that way).
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdBase::CmdFinishedTellInvoker( void ) const
+{
+ CMICmdInvoker::Instance().CmdExecuteFinished( const_cast< CMICmdBase & >( *this ) );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Returns the final version of the MI result record built up in the command's
+// Acknowledge function. The one line text of MI result.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - MI text version of the MI result record.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdBase::GetMIResultRecord( void ) const
+{
+ return m_miResultRecord.GetString();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve from the command additional MI result to its 1 line response.
+// Because of using LLDB addtional 'fake'/hack output is sometimes required to
+// help the driver client operate i.e. Eclipse.
+// Type: Overridden.
+// Args: None.
+// Return: CMIUtilString & - MI text version of the MI result record.
+// Throws: None.
+//--
+const CMIUtilString & CMICmdBase::GetMIResultRecordExtra( void ) const
+{
+ return m_miResultRecordExtra;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Hss *this command got additional MI result to its 1 line response.
+// Because of using LLDB addtional 'fake'/hack output is sometimes required to
+// help the driver client operate i.e. Eclipse.
+// Type: Overridden.
+// Args: None.
+// Return: bool - True = Yes have additional MI output, false = no nothing extra.
+// Throws: None.
+//--
+bool CMICmdBase::HasMIResultRecordExtra( void ) const
+{
+ return m_bHasResultRecordExtra;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Short cut function to enter error information into the command's metadata
+// object and set the command's error status.
+// Type: Method.
+// Args: rErrMsg - (R) Error description.
+// Return: None.
+// Throws: None.
+//--
+void CMICmdBase::SetError( const CMIUtilString & rErrMsg )
+{
+ m_cmdData.bCmdValid = false;
+ m_cmdData.strErrorDescription = rErrMsg;
+ m_cmdData.bCmdExecutedSuccessfully = false;
+
+ const CMICmnMIValueResult valueResult( "msg", CMICmnMIValueConst( rErrMsg ) );
+ const CMICmnMIResultRecord miResultRecord( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult );
+ m_miResultRecord = miResultRecord;
+ m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Ask a command to provide its unique identifier.
+// Type: Method.
+// Args: A unique identifier for this command class.
+// Return: None.
+// Throws: None.
+//--
+MIuint CMICmdBase::GetGUID( void )
+{
+ MIuint64 vptr = reinterpret_cast< MIuint64 >( this );
+ MIuint id = (vptr ) & 0xFFFFFFFF;
+ id ^= (vptr >> 32) & 0xFFFFFFFF;
+
+ return id;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdBase::ParseArgs( void )
+{
+ // Do nothing - override to implement
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument or option
+// definitions for the command to handle proceed to parse and validate the
+// command's options text for those arguments and extract the values for each if
+// any.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdBase::ParseValidateCmdOptions( void )
+{
+ CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
+ if( m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
+ return MIstatus::success;
+
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: If the MI Driver is not operating via a client i.e. Eclipse but say operating
+// on a executable passed in as a argument to the drive then what should the driver
+// do on a command failing? Either continue operating or exit the application.
+// Override this function where a command failure cannot allow the driver to
+// continue operating.
+// Type: Overrideable.
+// Args: None.
+// Return: bool - True = Fatal if command fails, false = can continue if command fails.
+// Throws: None.
+//--
+bool CMICmdBase::GetExitAppOnCommandFailure( void ) const
+{
+ return false;
+}
diff --git a/tools/lldb-mi/MICmdBase.h b/tools/lldb-mi/MICmdBase.h
new file mode 100644
index 000000000000..b05e97d2082d
--- /dev/null
+++ b/tools/lldb-mi/MICmdBase.h
@@ -0,0 +1,156 @@
+//===-- MICmdBase.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdBase.h
+//
+// Overview: CMICmdBase interface.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MIUtilString.h"
+#include "MICmnBase.h"
+#include "MICmnResources.h"
+#include "MICmdInvoker.h"
+#include "MICmdFactory.h"
+#include "MICmdData.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmdArgSet.h"
+
+// Declarations:
+class CMICmnLLDBDebugSessionInfo;
+
+//++ ============================================================================
+// Details: MI command base class. MI commands derive from this base class.
+// The Command Factory creates command objects and passes them to the
+// Command Invoker. The Invoker takes ownersip of any commands created
+// which means it is the only object to delete them when a command is
+// finished working. Commands do not delete themselves.
+// There are two types of command implicitly defined by the state of
+// the m_bWaitForEventFromSBDebugger flag. There is the event type
+// command which registers (command fn) callbacks with the SBListener
+// does some work then wakes up again when called back, does more work
+// perhaps, ends, then the Invoker calls the command's Acknowledge
+// function. The other type of command is one that just does some work,
+// ends, then the Invoker calls the command's Acknowledge function. No
+// events set up.
+// A command's Execute(), Acknowledge() and event callback functions are
+// carried out in the main thread.
+// A command may use the argument derived object classes (CMICmdArgValBase)
+// to factor handling and parsing of different types of arguments
+// presented to a command. A command will produce an error should it
+// be presented with arguments or options it does not understand.
+// Gotchas: None.
+// Authors: Illya Rudkin 18/02/2014.
+// Changes: None.
+//--
+class CMICmdBase
+: public CMICmnBase
+, public CMICmdInvoker::ICmd
+, public CMICmdFactory::ICmd
+{
+// Methods:
+public:
+ /* ctor */ CMICmdBase( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual const SMICmdData & GetCmdData( void ) const;
+ virtual const CMIUtilString & GetErrorDescription( void ) const;
+ virtual bool SetCmdData( const SMICmdData & vCmdData );
+ virtual void CmdFinishedTellInvoker( void ) const;
+ virtual const CMIUtilString & GetMIResultRecord( void ) const;
+ virtual const CMIUtilString & GetMIResultRecordExtra( void ) const;
+ virtual bool HasMIResultRecordExtra( void ) const;
+ virtual bool ParseArgs( void );
+ // From CMICmdFactory::ICmd
+ virtual const CMIUtilString & GetMiCmd( void ) const;
+ virtual CMICmdFactory::CmdCreatorFnPtr GetCmdCreatorFn( void ) const;
+
+ virtual MIuint GetGUID( void );
+
+// Overrideable:
+public:
+ /* dtor */ virtual ~CMICmdBase( void );
+ virtual bool GetExitAppOnCommandFailure( void ) const;
+
+// Methods:
+protected:
+ void SetError( const CMIUtilString & rErrMsg );
+ template< class T >
+ T * GetOption( const CMIUtilString & vStrOptionName );
+ bool ParseValidateCmdOptions( void );
+
+// Attributes:
+protected:
+ CMICmdFactory::CmdCreatorFnPtr m_pSelfCreatorFn;
+ CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge function failure
+ SMICmdData m_cmdData; // Holds information/status of *this command. Used by other MI code to report or determine state of a command.
+ bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait, false = command calls Acknowledge() straight after Execute() no waiting
+ CMIUtilString m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert'
+ CMICmnMIResultRecord m_miResultRecord; // This is completed in the Acknowledge() function and returned to the Command Invoker to proceed stdout output. Each command forms 1 response to its input.
+ CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge() function and returned to the Command Invoker to proceed stdout output. Hack command produce more response text to help the client because of using LLDB
+ CMICmnLLDBDebugSessionInfo & m_rLLDBDebugSessionInfo; // Access to command sharing information or data across any and all command based derived classes.
+ bool m_bHasResultRecordExtra; // True = Yes command produced additional MI output to its 1 line response, false = no extra MI output formed.
+ CMICmdArgSet m_setCmdArgs; // The list of arguments *this command needs to parse from the options string to carry out work.
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the command argument or option object pointer so that it can be
+// examined. If the option found and valid get the value (number, string or list
+// - see CMICmdArgValBase class) from it to use with the command's decision
+// making. If the argument is not found the command's error description is set
+// describing the error condition.
+// Type: Template method.
+// Args: vStrOptionName - (R) The text name of the argument or option to search for in
+// the list of the command's possible arguments or options.
+// Return: T * - CMICmdArgValBase derived object.
+// - NULL = function has failed, unable to retrieve the option/arg object.
+// Throws: None.
+//--
+template< class T >
+T * CMICmdBase::GetOption( const CMIUtilString & vStrOptionName )
+{
+ CMICmdArgValBase * pPtrBase = nullptr;
+ if( !m_setCmdArgs.GetArg( vStrOptionName, pPtrBase ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), vStrOptionName.c_str() ) );
+ return nullptr;
+ }
+
+ return static_cast< T * >( pPtrBase );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the command argument or option object pointer using template function
+// CMICmdBase::GetOption(). Should the argument (by name) not be found the
+// command will exit with a failure (set in GetOption()).
+// Type: Preprocessor macro.
+// Args: a - (R) The actual variable's name.
+// b - (R) The type of variable (appended to CMICmdArgVal i.e. CMICmdArgValString).
+// c - (R) The text name of the argument or option to search for in the list of
+// the command's possible arguments or options.
+// Return: T * - CMICmdArgValBase derived object.
+// - NULL = function has failed, unable to retrieve the option/arg object.
+// Throws: None.
+//--
+#define CMICMDBASE_GETOPTION( a, b, c ) \
+ CMICmdArgVal##b * a = CMICmdBase::GetOption< CMICmdArgVal##b >( c );\
+ if( a == nullptr ) \
+ return MIstatus::failure;
+// This comment is to stop compile warning for #define
diff --git a/tools/lldb-mi/MICmdCmd.cpp b/tools/lldb-mi/MICmdCmd.cpp
new file mode 100644
index 000000000000..3c6d52b24769
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmd.cpp
@@ -0,0 +1,174 @@
+//===-- MICmdCmd.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmd.cpp
+//
+// Overview: CMICmdCmdEnablePrettyPrinting implementation.
+// CMICmdCmdSource implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmd.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdEnablePrettyPrinting constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdEnablePrettyPrinting::CMICmdCmdEnablePrettyPrinting( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "enable-pretty-printing";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdEnablePrettyPrinting::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdEnablePrettyPrinting destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdEnablePrettyPrinting::~CMICmdCmdEnablePrettyPrinting( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdEnablePrettyPrinting::Execute( void )
+{
+ // Do nothing
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdEnablePrettyPrinting::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( "0" );
+ const CMICmnMIValueResult miValueResult( "supported", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdEnablePrettyPrinting::CreateSelf( void )
+{
+ return new CMICmdCmdEnablePrettyPrinting();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSource constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSource::CMICmdCmdSource( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "source";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdSource::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSource destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSource::~CMICmdCmdSource( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSource::Execute( void )
+{
+ // Do nothing
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSource::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdSource::CreateSelf( void )
+{
+ return new CMICmdCmdSource();
+}
diff --git a/tools/lldb-mi/MICmdCmd.h b/tools/lldb-mi/MICmdCmd.h
new file mode 100644
index 000000000000..c2ab6896e689
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmd.h
@@ -0,0 +1,104 @@
+//===-- MICmdCmd.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmd.h
+//
+// Overview: CMICmdCmdEnablePrettyPrinting interface.
+// CMICmdCmdSource interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+/*
+MI commands implemented are:
+ See MICmdCommands.cpp
+*/
+
+#pragma once
+
+// Third party headers:
+#include <vector>
+#include <lldb/API/SBBreakpoint.h>
+#include <lldb/API/SBCommandReturnObject.h>
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "enable-pretty-printing".
+// Enables Python base pretty printing.
+// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Variable-Objects.html
+// Gotchas: None.
+// Authors: Illya Rudkin 03/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdEnablePrettyPrinting : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdEnablePrettyPrinting( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdEnablePrettyPrinting( void );
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "source".
+// Gotchas: None.
+// Authors: Illya Rudkin 05/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdSource
+ : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdSource( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdSource( void );
+};
diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp
new file mode 100644
index 000000000000..f0e9acfe9082
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdBreak.cpp
@@ -0,0 +1,1026 @@
+//===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdBreak.cpp
+//
+// Overview: CMICmdCmdBreakInsert implementation.
+// CMICmdCmdBreakDelete implementation.
+// CMICmdCmdBreakDisable implementation.
+// CMICmdCmdBreakEnable implementation.
+// CMICmdCmdBreakAfter implementation.
+// CMICmdCmdBreakCondition implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBBreakpointLocation.h>
+
+// In-house headers:
+#include "MICmdCmdBreak.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIOutOfBandRecord.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmnStreamStdout.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakInsert constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
+: m_bBrkPtIsTemp( false )
+, m_bBrkPtIsPending( false )
+, m_nBrkPtIgnoreCount( 0 )
+, m_bBrkPtEnabled( false )
+, m_bBrkPtCondition( false )
+, m_bBrkPtThreadId( false )
+, m_nBrkPtThreadId( 0 )
+, m_constStrArgNamedTempBrkPt( "t" )
+, m_constStrArgNamedHWBrkPt( "h" )
+, m_constStrArgNamedPendinfBrkPt( "f" )
+, m_constStrArgNamedDisableBrkPt( "d" )
+, m_constStrArgNamedTracePt( "a" )
+, m_constStrArgNamedConditionalBrkPt( "c" )
+, m_constStrArgNamedInoreCnt( "i" )
+, m_constStrArgNamedRestrictBrkPtToThreadId( "p" )
+, m_constStrArgNamedLocation( "location" )
+, m_constStrArgNamedThreadGroup( "thread-group" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-insert";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakInsert destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakInsert::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTempBrkPt, false, true )) );
+ //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedDisableBrkPt, false, false ) ) );
+ //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuoted, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedLocation, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakInsert::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt );
+ CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup );
+ CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation );
+ CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt );
+ CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt );
+ CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt );
+ CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt );
+ CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId );
+
+ m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
+ m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
+ m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
+ if( m_bHaveArgOptionThreadGrp )
+ {
+ MIuint nThreadGrp = 0;
+ pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp );
+ m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp );
+ }
+ m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
+ if( pArgLocation->GetFound() )
+ m_brkName = pArgLocation->GetValue();
+ else if( m_bBrkPtIsPending )
+ {
+ pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName );
+ }
+ if( pArgIgnoreCnt->GetFound() )
+ {
+ pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount );
+ }
+ m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
+ if( m_bBrkPtCondition )
+ {
+ pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition );
+ }
+ m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
+ if( m_bBrkPtCondition )
+ {
+ pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId );
+ }
+
+ // Determine if break on a file line or at a function
+ BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
+ const CMIUtilString cColon = ":";
+ CMIUtilString fileName;
+ MIuint nFileLine = 0;
+ CMIUtilString strFileFn;
+ const MIint nPosColon = m_brkName.find( cColon );
+ if( nPosColon != (MIint) std::string::npos )
+ {
+ CMIUtilString::VecString_t vecFileAndLocation;
+ const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits );
+ if( vecFileAndLocation.size() != 2 )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
+ return MIstatus::failure;
+ }
+ fileName = vecFileAndLocation.at( 0 );
+ const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) );
+ if( rStrLineOrFn.empty() )
+ eBrkPtType = eBreakPoint_ByName;
+ else
+ {
+ MIint64 nValue = 0;
+ if( rStrLineOrFn.ExtractNumber( nValue ) )
+ {
+ nFileLine = static_cast< MIuint >( nValue );
+ eBrkPtType = eBreakPoint_ByFileLine;
+ }
+ else
+ {
+ strFileFn = rStrLineOrFn;
+ eBrkPtType = eBreakPoint_ByFileFn;
+ }
+ }
+ }
+
+ // Determine if break defined as an address
+ lldb::addr_t nAddress = 0;
+ if( eBrkPtType == eBreakPoint_NotDefineYet )
+ {
+ MIint64 nValue = 0;
+ if( m_brkName.ExtractNumber( nValue ) )
+ {
+ nAddress = static_cast< lldb::addr_t >( nValue );
+ eBrkPtType = eBreakPoint_ByAddress;
+ }
+ }
+
+ // Break defined as an function
+ if( eBrkPtType == eBreakPoint_NotDefineYet )
+ {
+ eBrkPtType = eBreakPoint_ByName;
+ }
+
+ // Ask LLDB to create a breakpoint
+ bool bOk = MIstatus::success;
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
+ switch( eBrkPtType )
+ {
+ case eBreakPoint_ByAddress:
+ m_brkPt = rTarget.BreakpointCreateByAddress( nAddress );
+ break;
+ case eBreakPoint_ByFileFn:
+ m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() );
+ break;
+ case eBreakPoint_ByFileLine:
+ m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine );
+ break;
+ case eBreakPoint_ByName:
+ m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() );
+ break;
+ case eBreakPoint_count:
+ case eBreakPoint_NotDefineYet:
+ case eBreakPoint_Invalid:
+ bOk = MIstatus::failure;
+ break;
+ }
+
+ if( bOk )
+ {
+ m_brkPt.SetEnabled( m_bBrkPtEnabled );
+ m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount );
+ if( m_bBrkPtCondition )
+ m_brkPt.SetCondition( m_brkPtCondition.c_str() );
+ if( m_bBrkPtThreadId )
+ m_brkPt.SetThreadID( m_nBrkPtThreadId );
+ if( !m_brkPt.IsValid() )
+ m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
+ }
+
+ // CODETAG_LLDB_BREAKPOINT_CREATION
+ // This is in the main thread
+ // Record break point information to be by LLDB event handler function
+ CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
+ sBrkPtInfo.m_id = m_brkPt.GetID();
+ sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
+ sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
+ sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
+ sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
+ sBrkPtInfo.m_strOrigLoc = m_brkName;
+ sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
+ sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
+ sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
+ sBrkPtInfo.m_strCondition = m_brkPtCondition;
+ sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
+ sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
+ bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo );
+
+ if( !bOk )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ // CODETAG_LLDB_BRKPT_ID_MAX
+ if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakInsert::Acknowledge( void )
+{
+ // Get breakpoint information
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
+ if( !rSessionInfo.GetBrkPtInfo( m_brkPt, sBrkPtInfo ) )
+ {
+ return MIstatus::failure;
+ }
+
+ // CODETAG_LLDB_BREAKPOINT_CREATION
+ // Add more breakpoint information or overwrite existing information
+ sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
+ sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
+ sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
+ sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
+ sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations();
+ sBrkPtInfo.m_strOrigLoc = m_brkName;
+ sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
+ sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
+ sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
+ sBrkPtInfo.m_strCondition = m_brkPtCondition;
+ sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
+ sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
+
+ // MI print "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
+ CMICmnMIValueTuple miValueTuple;
+ if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
+ {
+ return MIstatus::failure;
+ }
+
+ const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakInsert::CreateSelf( void )
+{
+ return new CMICmdCmdBreakInsert();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDelete constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void )
+: m_constStrArgNamedBrkPt( "breakpoint" )
+, m_constStrArgNamedThreadGrp( "thread-group" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-delete";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDelete destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDelete::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDelete::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
+
+ // ATM we only handle one break point ID
+ MIuint64 nBrk = UINT64_MAX;
+ if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete( static_cast< lldb::break_id_t >( nBrk ) );
+ if( !bBrkPt )
+ {
+ const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDelete::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakDelete::CreateSelf( void )
+{
+ return new CMICmdCmdBreakDelete();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDisable constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDisable::CMICmdCmdBreakDisable( void )
+: m_constStrArgNamedThreadGrp( "thread-group" )
+, m_constStrArgNamedBrkPt( "breakpoint" )
+, m_bBrkPtDisabledOk( false )
+, m_nBrkPtId( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-disable";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDisable destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDisable::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDisable::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
+
+ // ATM we only handle one break point ID
+ MIuint64 nBrk = UINT64_MAX;
+ if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
+ if( brkPt.IsValid() )
+ {
+ m_bBrkPtDisabledOk = true;
+ brkPt.SetEnabled( false );
+ m_nBrkPtId = nBrk;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakDisable::Acknowledge( void )
+{
+ if( m_bBrkPtDisabledOk )
+ {
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ const CMICmnMIValueResult miValueResult( "number", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( "n" );
+ const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
+ bool bOk = miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
+ const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
+ bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+ return bOk;
+ }
+
+ const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakDisable::CreateSelf( void )
+{
+ return new CMICmdCmdBreakDisable();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakEnable constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakEnable::CMICmdCmdBreakEnable( void )
+: m_constStrArgNamedThreadGrp( "thread-group" )
+, m_constStrArgNamedBrkPt( "breakpoint" )
+, m_bBrkPtEnabledOk( false )
+, m_nBrkPtId( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-enable";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakEnable destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakEnable::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakEnable::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
+
+ // ATM we only handle one break point ID
+ MIuint64 nBrk = UINT64_MAX;
+ if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
+ if( brkPt.IsValid() )
+ {
+ m_bBrkPtEnabledOk = true;
+ brkPt.SetEnabled( false );
+ m_nBrkPtId = nBrk;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakEnable::Acknowledge( void )
+{
+ if( m_bBrkPtEnabledOk )
+ {
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ const CMICmnMIValueResult miValueResult( "number", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( "y" );
+ const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
+ bool bOk = miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
+ const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
+ bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+ return bOk;
+ }
+
+ const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakEnable::CreateSelf( void )
+{
+ return new CMICmdCmdBreakEnable();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakAfter constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakAfter::CMICmdCmdBreakAfter( void )
+: m_constStrArgNamedThreadGrp( "thread-group" )
+, m_constStrArgNamedNumber( "number" )
+, m_constStrArgNamedCount( "count" )
+, m_nBrkPtId( 0 )
+, m_nBrkPtCount( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-after";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakAfter destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakAfter::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedCount, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakAfter::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
+ CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount );
+
+ m_nBrkPtId = pArgNumber->GetValue();
+ m_nBrkPtCount = pArgCount->GetValue();
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
+ if( brkPt.IsValid() )
+ {
+ brkPt.SetIgnoreCount( m_nBrkPtCount );
+
+ CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
+ if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
+ return MIstatus::failure;
+ }
+ sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
+ rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
+ }
+ else
+ {
+ const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakAfter::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakAfter::CreateSelf( void )
+{
+ return new CMICmdCmdBreakAfter();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakCondition constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakCondition::CMICmdCmdBreakCondition( void )
+: m_constStrArgNamedThreadGrp( "thread-group" )
+, m_constStrArgNamedNumber( "number" )
+, m_constStrArgNamedExpr( "expr" )
+, m_constStrArgNamedExprNoQuotes( "expression not surround by quotes" ) // Not specified in MI spec, we need to handle expressions not surrounded by quotes
+, m_nBrkPtId( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-condition";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakCondition destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakCondition::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedExpr, true, true, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedExprNoQuotes, true, false, CMICmdArgValListBase::eArgValType_StringQuotedNumber ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakCondition::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
+ CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr );
+
+ m_nBrkPtId = pArgNumber->GetValue();
+ m_strBrkPtExpr = pArgExpr->GetValue();
+ m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
+ if( brkPt.IsValid() )
+ {
+ brkPt.SetCondition( m_strBrkPtExpr.c_str() );
+
+ CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
+ if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
+ return MIstatus::failure;
+ }
+ sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
+ rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
+ }
+ else
+ {
+ const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdBreakCondition::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdBreakCondition::CreateSelf( void )
+{
+ return new CMICmdCmdBreakCondition();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: A breakpoint expression can be passed to *this command as:
+// a single string i.e. '2' -> ok.
+// a quoted string i.e. "a > 100" -> ok
+// a non quoted string i.e. 'a > 100' -> not ok
+// CMICmdArgValString only extracts the first space seperated string, the "a".
+// This function using the optional argument type CMICmdArgValListOfN collects
+// the rest of the expression so that is may be added to the 'a' part to form a
+// complete expression string i.e. "a > 100".
+// If the expression value was guaranteed to be surrounded by quotes them this
+// function would not be necessary.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - Rest of the breakpoint expression.
+// Throws: None.
+//--
+CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void )
+{
+ CMIUtilString strExpression;
+
+ CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes );
+ if( pArgExprNoQuotes != nullptr )
+ {
+ CMIUtilString strExpression;
+ const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() );
+ if( !rVecExprParts.empty() )
+ {
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
+ while( it != rVecExprParts.end() )
+ {
+ const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it );
+ const CMIUtilString & rPartExpr = pPartExpr->GetValue();
+ strExpression += " ";
+ strExpression += rPartExpr;
+
+ // Next
+ ++it;
+ }
+ strExpression = strExpression.Trim();
+ }
+ }
+
+ return strExpression;
+}
diff --git a/tools/lldb-mi/MICmdCmdBreak.h b/tools/lldb-mi/MICmdCmdBreak.h
new file mode 100644
index 000000000000..e5283d609905
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdBreak.h
@@ -0,0 +1,292 @@
+//===-- MICmdCmdBreak.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdBreak.h
+//
+// Overview: CMICmdCmdBreakInsert interface.
+// CMICmdCmdBreakDelete interface.
+// CMICmdCmdBreakDisable interface.
+// CMICmdCmdBreakEnable interface.
+// CMICmdCmdBreakAfter interface.
+// CMICmdCmdBreakCondition interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <lldb/API/SBBreakpoint.h>
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-insert".
+// This command does not follow the MI documentation exactly.
+// Gotchas: None.
+// Authors: Illya Rudkin 11/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakInsert : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakInsert( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakInsert( void );
+
+// Enumerations:
+private:
+ //++ ===================================================================
+ // Details: The type of break point give in the MI command text.
+ //--
+ enum BreakPoint_e
+ {
+ eBreakPoint_Invalid = 0,
+ eBreakPoint_ByFileLine,
+ eBreakPoint_ByFileFn,
+ eBreakPoint_ByName,
+ eBreakPoint_ByAddress,
+ eBreakPoint_count,
+ eBreakPoint_NotDefineYet
+ };
+
+// Attributes:
+private:
+ bool m_bBrkPtIsTemp;
+ bool m_bHaveArgOptionThreadGrp;
+ CMIUtilString m_brkName;
+ CMIUtilString m_strArgOptionThreadGrp;
+ lldb::SBBreakpoint m_brkPt;
+ bool m_bBrkPtIsPending;
+ MIuint m_nBrkPtIgnoreCount;
+ bool m_bBrkPtEnabled;
+ bool m_bBrkPtCondition;
+ CMIUtilString m_brkPtCondition;
+ bool m_bBrkPtThreadId;
+ MIuint m_nBrkPtThreadId;
+ const CMIUtilString m_constStrArgNamedTempBrkPt;
+ const CMIUtilString m_constStrArgNamedHWBrkPt; // Not handled by *this command
+ const CMIUtilString m_constStrArgNamedPendinfBrkPt;
+ const CMIUtilString m_constStrArgNamedDisableBrkPt;
+ const CMIUtilString m_constStrArgNamedTracePt; // Not handled by *this command
+ const CMIUtilString m_constStrArgNamedConditionalBrkPt;
+ const CMIUtilString m_constStrArgNamedInoreCnt;
+ const CMIUtilString m_constStrArgNamedRestrictBrkPtToThreadId;
+ const CMIUtilString m_constStrArgNamedLocation;
+ const CMIUtilString m_constStrArgNamedThreadGroup; // Not specified in MI spec but Eclipse gives this option sometimes
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-delete".
+// Gotchas: None.
+// Authors: Illya Rudkin 11/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakDelete : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakDelete( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakDelete( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedBrkPt;
+ const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-disable".
+// Gotchas: None.
+// Authors: Illya Rudkin 19/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakDisable : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakDisable( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakDisable( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNamedBrkPt;
+ bool m_bBrkPtDisabledOk;
+ MIuint m_nBrkPtId;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-enable".
+// Gotchas: None.
+// Authors: Illya Rudkin 19/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakEnable : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakEnable( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakEnable( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNamedBrkPt;
+ bool m_bBrkPtEnabledOk;
+ MIuint m_nBrkPtId;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-after".
+// Gotchas: None.
+// Authors: Illya Rudkin 29/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakAfter : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakAfter( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakAfter( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNamedNumber;
+ const CMIUtilString m_constStrArgNamedCount;
+ MIuint m_nBrkPtId;
+ MIuint m_nBrkPtCount;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "break-condition".
+// Gotchas: None.
+// Authors: Illya Rudkin 29/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdBreakCondition : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdBreakCondition( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdBreakCondition( void );
+
+// Methods:
+private:
+ CMIUtilString GetRestOfExpressionNotSurroundedInQuotes( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNamedNumber;
+ const CMIUtilString m_constStrArgNamedExpr;
+ const CMIUtilString m_constStrArgNamedExprNoQuotes; // Not specified in MI spec, we need to handle expressions not surrounded by quotes
+ MIuint m_nBrkPtId;
+ CMIUtilString m_strBrkPtExpr;
+};
diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp
new file mode 100644
index 000000000000..69012ef042c4
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdData.cpp
@@ -0,0 +1,1365 @@
+//===-- MICmdCmdData.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdData.cpp
+//
+// Overview: CMICmdCmdDataEvaluateExpression implementation.
+// CMICmdCmdDataDisassemble implementation.
+// CMICmdCmdDataReadMemoryBytes implementation.
+// CMICmdCmdDataReadMemory implementation.
+// CMICmdCmdDataListRegisterNames implementation.
+// CMICmdCmdDataListRegisterValues implementation.
+// CMICmdCmdDataListRegisterChanged implementation.
+// CMICmdCmdDataWriteMemoryBytes implementation.
+// CMICmdCmdDataWriteMemory implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBThread.h>
+#include <lldb/API/SBInstruction.h>
+#include <lldb/API/SBInstructionList.h>
+#include <lldb/API/SBStream.h>
+
+// In-house headers:
+#include "MICmdCmdData.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmnLLDBProxySBValue.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmdArgValConsume.h"
+#include "MICmnLLDBDebugSessionInfoVarObj.h"
+#include "MICmnLLDBUtilSBValue.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataEvaluateExpression constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression( void )
+: m_bExpressionValid( true )
+, m_bEvaluatedExpression( true )
+, m_strValue( "??" )
+, m_bCompositeVarType( false )
+, m_bFoundInvalidChar( false )
+, m_cExpressionInvalidChar( 0x00 )
+, m_constStrArgThread( "thread" )
+, m_constStrArgFrame( "frame" )
+, m_constStrArgExpr( "expr" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-evaluate-expression";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataEvaluateExpression destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataEvaluateExpression::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpr, true, true, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataEvaluateExpression::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgExpr );
+
+ const CMIUtilString & rExpression( pArgExpr->GetValue() );
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = rProcess.GetSelectedThread();
+ m_bExpressionValid = (thread.GetNumFrames() > 0);
+ if( !m_bExpressionValid )
+ return MIstatus::success;
+
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValue value = frame.EvaluateExpression( rExpression.c_str() );
+ if( !value.IsValid() )
+ value = frame.FindVariable( rExpression.c_str() );
+ if( !value.IsValid() )
+ {
+ m_bEvaluatedExpression = false;
+ return MIstatus::success;
+ }
+ const CMICmnLLDBUtilSBValue utilValue( value );
+ if( !utilValue.HasName() )
+ {
+ if( HaveInvalidCharacterInExpression( rExpression, m_cExpressionInvalidChar ) )
+ {
+ m_bFoundInvalidChar = true;
+ return MIstatus::success;
+ }
+
+ m_strValue = rExpression;
+ return MIstatus::success;
+ }
+ if( rExpression.IsQuoted() )
+ {
+ m_strValue = rExpression.Trim( '\"' );
+ return MIstatus::success;
+ }
+
+ MIuint64 nNumber = 0;
+ if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nNumber ) == MIstatus::success )
+ {
+ const lldb::ValueType eValueType = value.GetValueType(); MIunused( eValueType );
+ m_strValue = utilValue.GetValue();
+ CMIUtilString strCString;
+ if( CMICmnLLDBProxySBValue::GetCString( value, strCString ) )
+ {
+ m_strValue += CMIUtilString::Format( " '%s'", strCString.c_str() );
+ }
+ return MIstatus::success;
+ }
+
+ // Composite type i.e. struct
+ m_bCompositeVarType = true;
+ const MIuint nChild = value.GetNumChildren();
+ for( MIuint i = 0; i < nChild; i++ )
+ {
+ lldb::SBValue member = value.GetChildAtIndex( i );
+ const bool bValid = member.IsValid();
+ CMIUtilString strType( MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ) );
+ if( bValid )
+ {
+ const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) );
+ const char * pTypeName = member.GetName();
+ if( pTypeName != nullptr )
+ strType = pTypeName;
+
+ // MI print "{variable = 1, variable2 = 3, variable3 = 5}"
+ const bool bNoQuotes = true;
+ const CMICmnMIValueConst miValueConst( strValue, bNoQuotes );
+ const bool bUseSpaces = true;
+ const CMICmnMIValueResult miValueResult( strType, miValueConst, bUseSpaces );
+ m_miValueTuple.Add( miValueResult, bUseSpaces );
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataEvaluateExpression::Acknowledge( void )
+{
+ if( m_bExpressionValid )
+ {
+ if( m_bEvaluatedExpression )
+ {
+ if( m_bCompositeVarType )
+ {
+ const CMICmnMIValueConst miValueConst( m_miValueTuple.GetString() );
+ const CMICmnMIValueResult miValueResult( "value", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ if( m_bFoundInvalidChar )
+ {
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "Invalid character '%c' in expression", m_cExpressionInvalidChar ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( m_strValue );
+ const CMICmnMIValueResult miValueResult( "value", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( "Could not evaluate expression" );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( "Invalid expression" );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataEvaluateExpression::CreateSelf( void )
+{
+ return new CMICmdCmdDataEvaluateExpression();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the expression string to see if it contains invalid characters.
+// Type: Method.
+// Args: vrExpr - (R) Expression string given to *this command.
+// vrwInvalidChar - (W) True = Invalid character found, false = nothing found.
+// Return: bool - True = Invalid character found, false = nothing found.
+// Throws: None.
+//--
+bool CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression( const CMIUtilString & vrExpr, MIchar & vrwInvalidChar )
+{
+ bool bFoundInvalidCharInExpression = false;
+ vrwInvalidChar = 0x00;
+
+ if( vrExpr.at( 0 ) == '\\' )
+ {
+ // Example: Mouse hover over "%5d" expression has \"%5d\" in it
+ bFoundInvalidCharInExpression = true;
+ vrwInvalidChar = '\\';
+ }
+
+ return bFoundInvalidCharInExpression;
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataDisassemble constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgAddrStart( "s" )
+, m_constStrArgAddrEnd( "e" )
+, m_constStrArgConsume( "--" )
+, m_constStrArgMode( "mode" )
+, m_miValueList( true )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-disassemble";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataDisassemble destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataDisassemble::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrEnd, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValConsume( m_constStrArgConsume, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMode, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataDisassemble::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgAddrStart, OptionShort, m_constStrArgAddrStart );
+ CMICMDBASE_GETOPTION( pArgAddrEnd, OptionShort, m_constStrArgAddrEnd );
+ CMICMDBASE_GETOPTION( pArgMode, Number, m_constStrArgMode );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+ CMIUtilString strAddrStart;
+ if( !pArgAddrStart->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrStart ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) );
+ return MIstatus::failure;
+ }
+ MIint64 nAddrStart = 0;
+ if( !strAddrStart.ExtractNumber( nAddrStart ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMIUtilString strAddrEnd;
+ if( !pArgAddrEnd->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrEnd ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) );
+ return MIstatus::failure;
+ }
+ MIint64 nAddrEnd = 0;
+ if( !strAddrEnd.ExtractNumber( nAddrEnd ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) );
+ return MIstatus::failure;
+ }
+ const MIuint nDisasmMode = pArgMode->GetValue();
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
+ lldb::addr_t lldbStartAddr = static_cast< lldb::addr_t >( nAddrStart );
+ lldb::SBInstructionList instructions = rTarget.ReadInstructions( lldb::SBAddress( lldbStartAddr, rTarget ), nAddrEnd - nAddrStart );
+ const MIuint nInstructions = instructions.GetSize();
+ for( size_t i = 0; i < nInstructions; i++ )
+ {
+ const MIchar * pUnknown = "??";
+ lldb::SBInstruction instrt = instructions.GetInstructionAtIndex( i );
+ const MIchar * pStrMnemonic = instrt.GetMnemonic( rTarget );
+ pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
+ lldb::SBAddress address = instrt.GetAddress();
+ lldb::addr_t addr = address.GetLoadAddress( rTarget );
+ const MIchar * pFnName = address.GetFunction().GetName();
+ pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
+ lldb::addr_t addrOffSet = address.GetOffset();
+ const MIchar * pStrOperands = instrt.GetOperands( rTarget );
+ pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
+
+ // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08llx", addr ) );
+ const CMICmnMIValueResult miValueResult( "address", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( pFnName );
+ const CMICmnMIValueResult miValueResult2( "func-name", miValueConst2 );
+ miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%lld", addrOffSet ) );
+ const CMICmnMIValueResult miValueResult3( "offset", miValueConst3 );
+ miValueTuple.Add( miValueResult3 );
+ const CMICmnMIValueConst miValueConst4( CMIUtilString::Format( "%s %s", pStrMnemonic, pStrOperands ) );
+ const CMICmnMIValueResult miValueResult4( "inst", miValueConst4 );
+ miValueTuple.Add( miValueResult4 );
+
+ if( nDisasmMode == 1 )
+ {
+ lldb::SBLineEntry lineEntry = address.GetLineEntry();
+ const MIuint nLine = lineEntry.GetLine();
+ const MIchar * pFileName = lineEntry.GetFileSpec().GetFilename();
+ pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
+
+ // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%u", nLine ) );
+ const CMICmnMIValueResult miValueResult( "line", miValueConst );
+ CMICmnMIValueTuple miValueTuple2( miValueResult );
+ const CMICmnMIValueConst miValueConst2( pFileName );
+ const CMICmnMIValueResult miValueResult2( "file", miValueConst2 );
+ miValueTuple2.Add( miValueResult2 );
+ const CMICmnMIValueList miValueList( miValueTuple );
+ const CMICmnMIValueResult miValueResult3( "line_asm_insn", miValueList );
+ miValueTuple2.Add( miValueResult3 );
+ const CMICmnMIValueResult miValueResult4( "src_and_asm_line", miValueTuple2 );
+ m_miValueList.Add( miValueResult4 );
+ }
+ else
+ {
+ m_miValueList.Add( miValueTuple );
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataDisassemble::Acknowledge( void )
+{
+ const CMICmnMIValueResult miValueResult( "asm_insns", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataDisassemble::CreateSelf( void )
+{
+ return new CMICmdCmdDataDisassemble();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataReadMemoryBytes constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgByteOffset( "o" )
+, m_constStrArgAddrStart( "address" )
+, m_constStrArgNumBytes( "count" )
+, m_pBufferMemory( nullptr )
+, m_nAddrStart( 0 )
+, m_nAddrNumBytesToRead( 0 )
+, m_nAddrOffset( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-read-memory-bytes";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataReadMemoryBytes destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes( void )
+{
+ if( m_pBufferMemory != nullptr )
+ {
+ delete [] m_pBufferMemory;
+ m_pBufferMemory = nullptr;
+ }
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataReadMemoryBytes::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddrStart, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumBytes, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataReadMemoryBytes::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgAddrStart, Number, m_constStrArgAddrStart );
+ CMICMDBASE_GETOPTION( pArgAddrOffset, Number, m_constStrArgByteOffset );
+ CMICMDBASE_GETOPTION( pArgNumBytes, Number, m_constStrArgNumBytes );
+
+ const MIuint64 nAddrStart = pArgAddrStart->GetValue();
+ const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
+ if( pArgAddrOffset->GetFound() )
+ m_nAddrOffset = pArgAddrOffset->GetValue();
+
+ m_pBufferMemory = new MIuchar[ nAddrNumBytes ];
+ if( m_pBufferMemory == nullptr )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBError error;
+ const MIuint64 nReadBytes = rProcess.ReadMemory( static_cast< lldb::addr_t >( nAddrStart ), (void *) m_pBufferMemory, nAddrNumBytes, error );
+ if( nReadBytes != nAddrNumBytes )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart ) );
+ return MIstatus::failure;
+ }
+ if( error.Fail() )
+ {
+ lldb::SBStream err;
+ const bool bOk = error.GetDescription( err ); MIunused( bOk );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart, err.GetData() ) );
+ return MIstatus::failure;
+ }
+
+ m_nAddrStart = nAddrStart;
+ m_nAddrNumBytesToRead = nAddrNumBytes;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataReadMemoryBytes::Acknowledge( void )
+{
+ // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08x", m_nAddrStart ) );
+ const CMICmnMIValueResult miValueResult( "begin", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( CMIUtilString::Format( "0x%08x", m_nAddrOffset ) );
+ const CMICmnMIValueResult miValueResult2( "offset", miValueConst2 );
+ miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%08x", m_nAddrStart + m_nAddrNumBytesToRead ) );
+ const CMICmnMIValueResult miValueResult3( "end", miValueConst3 );
+ miValueTuple.Add( miValueResult3 );
+
+ // MI: contents=\" \"
+ CMIUtilString strContent;
+ strContent.reserve( (m_nAddrNumBytesToRead << 1) + 1 );
+ for( MIuint64 i = 0; i < m_nAddrNumBytesToRead; i ++ )
+ {
+ strContent += CMIUtilString::Format( "%02x", m_pBufferMemory[ i ] );
+ }
+ const CMICmnMIValueConst miValueConst4( strContent );
+ const CMICmnMIValueResult miValueResult4( "contents", miValueConst4 );
+ miValueTuple.Add( miValueResult4 );
+ const CMICmnMIValueList miValueList( miValueTuple );
+ const CMICmnMIValueResult miValueResult5( "memory", miValueList );
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataReadMemoryBytes::CreateSelf( void )
+{
+ return new CMICmdCmdDataReadMemoryBytes();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataReadMemory constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-read-memory";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataReadMemory destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataReadMemory::Execute( void )
+{
+ // Do nothing - command deprecated use "data-read-memory-bytes" command
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataReadMemory::Acknowledge( void )
+{
+ // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which causes this command not to be called
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataReadMemory::CreateSelf( void )
+{
+ return new CMICmdCmdDataReadMemory();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataListRegisterNames constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames( void )
+: m_constStrArgThreadGroup( "thread-group" )
+, m_constStrArgRegNo( "regno" )
+, m_miValueList( true )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-list-register-names";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataReadMemoryBytes destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterNames::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, false, CMICmdArgValListBase::eArgValType_Number ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterNames::Execute( void )
+{
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ if( !rProcess.IsValid() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValueList registers = frame.GetRegisters();
+ const MIuint nRegisters = registers.GetSize();
+ for( MIuint i = 0; i < nRegisters; i++ )
+ {
+ lldb::SBValue value = registers.GetValueAtIndex( i );
+ const MIuint nRegChildren = value.GetNumChildren();
+ for( MIuint j = 0; j < nRegChildren; j++ )
+ {
+ lldb::SBValue value2 = value.GetChildAtIndex( j );
+ if( value2.IsValid() )
+ {
+ const CMICmnMIValueConst miValueConst( CMICmnLLDBUtilSBValue( value2 ).GetName() );
+ m_miValueList.Add( miValueConst );
+ }
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterNames::Acknowledge( void )
+{
+ const CMICmnMIValueResult miValueResult( "register-names", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataListRegisterNames::CreateSelf( void )
+{
+ return new CMICmdCmdDataListRegisterNames();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataListRegisterValues constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgSkip( "skip-unavailable" )
+, m_constStrArgFormat( "fmt" )
+, m_constStrArgRegNo( "regno" )
+, m_miValueList( true )
+, m_pProcess( nullptr )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-list-register-values";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataListRegisterValues destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterValues::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgSkip, false, false ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFormat, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, true, CMICmdArgValListBase::eArgValType_Number ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterValues::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgFormat, String, m_constStrArgFormat );
+ CMICMDBASE_GETOPTION( pArgRegNo, ListOfN, m_constStrArgRegNo );
+
+ const CMIUtilString & rStrFormat( pArgFormat->GetValue() );
+ if( rStrFormat.length() != 1 )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
+ return MIstatus::failure;
+ }
+ const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar( rStrFormat[ 0 ] );
+ if( eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ if( !rProcess.IsValid() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
+ return MIstatus::failure;
+ }
+ m_pProcess = &rProcess;
+
+ const CMICmdArgValListBase::VecArgObjPtr_t & rVecRegNo( pArgRegNo->GetExpectedOptions() );
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
+ while( it != rVecRegNo.end() )
+ {
+ const CMICmdArgValNumber * pRegNo = static_cast< CMICmdArgValNumber * >( *it );
+ const MIuint nReg = pRegNo->GetValue();
+ lldb::SBValue regValue = GetRegister( nReg );
+ const CMIUtilString strRegValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( regValue, eFormat ) );
+
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%u", nReg ) );
+ const CMICmnMIValueResult miValueResult( "number", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( strRegValue );
+ const CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
+ miValueTuple.Add( miValueResult2 );
+ m_miValueList.Add( miValueTuple );
+
+ // Next
+ ++it;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterValues::Acknowledge( void )
+{
+ const CMICmnMIValueResult miValueResult( "register-values", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataListRegisterValues::CreateSelf( void )
+{
+ return new CMICmdCmdDataListRegisterValues();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBValue - LLDB SBValue object.
+// Throws: None.
+//--
+lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister( const MIuint vRegisterIndex ) const
+{
+ lldb::SBThread thread = m_pProcess->GetSelectedThread();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValueList registers = frame.GetRegisters();
+ const MIuint nRegisters = registers.GetSize();
+ for( MIuint i = 0; i < nRegisters; i++ )
+ {
+ lldb::SBValue value = registers.GetValueAtIndex( i );
+ const MIuint nRegChildren = value.GetNumChildren();
+ if( nRegChildren > 0 )
+ {
+ lldb::SBValue value2 = value.GetChildAtIndex( vRegisterIndex );
+ if( value2.IsValid() )
+ {
+ return value2;
+ }
+ }
+ }
+
+ return lldb::SBValue();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataListRegisterChanged constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-list-changed-registers";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataListRegisterChanged destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterChanged::Execute( void )
+{
+ // Do nothing
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataListRegisterChanged::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataListRegisterChanged::CreateSelf( void )
+{
+ return new CMICmdCmdDataListRegisterChanged();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataWriteMemoryBytes constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgAddr( "address" )
+, m_constStrArgContents( "contents" )
+, m_constStrArgCount( "count" )
+, m_nAddr( 0 )
+, m_nCount( 0 )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-write-memory-bytes";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataWriteMemoryBytes destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemoryBytes::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgAddr, true, true, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgContents, true, true, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgCount, false, true, false, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemoryBytes::Execute( void )
+{
+ // Do nothing - not reproduceable (yet) in Eclipse
+ //CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
+ //CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
+ //CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
+ //CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
+ //
+ // Numbers extracts as string types as they could be hex numbers
+ // '&' is not recognised and so has to be removed
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemoryBytes::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataWriteMemoryBytes::CreateSelf( void )
+{
+ return new CMICmdCmdDataWriteMemoryBytes();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataWriteMemory constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgOffset( "o" )
+, m_constStrArgAddr( "address" )
+, m_constStrArgD( "d" )
+, m_constStrArgNumber( "a number" )
+, m_constStrArgContents( "contents" )
+, m_nAddr( 0 )
+, m_nCount( 0 )
+, m_pBufferMemory( nullptr )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-write-memory";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataWriteMemory destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory( void )
+{
+ if( m_pBufferMemory != nullptr )
+ {
+ delete [] m_pBufferMemory;
+ m_pBufferMemory = nullptr;
+ }
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemory::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddr, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgD, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgContents, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemory::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
+ CMICMDBASE_GETOPTION( pArgAddr, Number, m_constStrArgAddr );
+ CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNumber );
+ CMICMDBASE_GETOPTION( pArgContents, Number, m_constStrArgContents );
+
+ MIuint nAddrOffset = 0;
+ if( pArgOffset->GetFound() && !pArgOffset->GetExpectedOption< CMICmdArgValNumber, MIuint>( nAddrOffset ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str() ) );
+ return MIstatus::failure;
+ }
+ m_nAddr = pArgAddr->GetValue();
+ m_nCount = pArgNumber->GetValue();
+ const MIuint64 nValue = pArgContents->GetValue();
+
+ m_pBufferMemory = new MIuchar [ m_nCount ];
+ if( m_pBufferMemory == nullptr )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), m_nCount ) );
+ return MIstatus::failure;
+ }
+ *m_pBufferMemory = static_cast< MIchar >( nValue );
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBError error;
+ lldb::addr_t addr = static_cast< lldb::addr_t >( m_nAddr + nAddrOffset );
+ const size_t nBytesWritten = rProcess.WriteMemory( addr, (const void *) m_pBufferMemory, (size_t) m_nCount, error );
+ if( nBytesWritten != static_cast< size_t >( m_nCount ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK ), m_cmdData.strMiCmd.c_str(), m_nCount, addr ) );
+ return MIstatus::failure;
+ }
+ if( error.Fail() )
+ {
+ lldb::SBStream err;
+ const bool bOk = error.GetDescription( err ); MIunused( bOk );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), m_nCount, addr, err.GetData() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdDataWriteMemory::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdDataWriteMemory::CreateSelf( void )
+{
+ return new CMICmdCmdDataWriteMemory();
+}
diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h
new file mode 100644
index 000000000000..c1501de3918f
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdData.h
@@ -0,0 +1,374 @@
+//===-- MICmdCmdData.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdData.h
+//
+// Overview: CMICmdCmdDataEvaluateExpression interface.
+// CMICmdCmdDataDisassemble interface.
+// CMICmdCmdDataReadMemoryBytes interface.
+// CMICmdCmdDataReadMemory interface.
+// CMICmdCmdDataListRegisterNames interface.
+// CMICmdCmdDataListRegisterValues interface.
+// CMICmdCmdDataListRegisterChanged interface.
+// CMICmdCmdDataWriteMemoryBytes interface.
+// CMICmdCmdDataWriteMemory interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-evaluate-expression".
+// Gotchas: None.
+// Authors: Illya Rudkin 26/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataEvaluateExpression : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataEvaluateExpression( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataEvaluateExpression( void );
+
+// Methods:
+private:
+ bool HaveInvalidCharacterInExpression( const CMIUtilString & vrExpr, MIchar & vrwInvalidChar );
+
+// Attributes:
+private:
+ bool m_bExpressionValid; // True = yes is valid, false = not valid
+ bool m_bEvaluatedExpression; // True = yes is expression evaluated, false = failed
+ CMIUtilString m_strValue;
+ CMICmnMIValueTuple m_miValueTuple;
+ bool m_bCompositeVarType; // True = yes composite type, false = internal type
+ bool m_bFoundInvalidChar; // True = yes found unexpected character in the expression, false = all ok
+ MIchar m_cExpressionInvalidChar;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgExpr;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-disassemble".
+// Gotchas: None.
+// Authors: Illya Rudkin 19/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataDisassemble : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataDisassemble( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataDisassemble( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgAddrStart; // MI spec non mandatory, *this command mandatory
+ const CMIUtilString m_constStrArgAddrEnd; // MI spec non mandatory, *this command mandatory
+ const CMIUtilString m_constStrArgConsume;
+ const CMIUtilString m_constStrArgMode;
+ CMICmnMIValueList m_miValueList;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-read-memory-bytes".
+// Gotchas: None.
+// Authors: Illya Rudkin 20/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataReadMemoryBytes : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataReadMemoryBytes( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataReadMemoryBytes( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgByteOffset;
+ const CMIUtilString m_constStrArgAddrStart;
+ const CMIUtilString m_constStrArgNumBytes;
+ MIuchar * m_pBufferMemory;
+ MIuint64 m_nAddrStart;
+ MIuint64 m_nAddrNumBytesToRead;
+ MIuint64 m_nAddrOffset;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-read-memory".
+// Gotchas: None.
+// Authors: Illya Rudkin 21/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataReadMemory : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataReadMemory( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataReadMemory( void );
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-list-register-names".
+// Gotchas: None.
+// Authors: Illya Rudkin 21/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataListRegisterNames : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataListRegisterNames( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataListRegisterNames( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThreadGroup; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgRegNo; // Not handled by *this command
+ CMICmnMIValueList m_miValueList;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-list-register-values".
+// Gotchas: None.
+// Authors: Illya Rudkin 21/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataListRegisterValues : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataListRegisterValues( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataListRegisterValues( void );
+
+// Methods:
+private:
+ lldb::SBValue GetRegister( const MIuint vRegisterIndex ) const;
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgSkip; // Not handled by *this command
+ const CMIUtilString m_constStrArgFormat;
+ const CMIUtilString m_constStrArgRegNo;
+ CMICmnMIValueList m_miValueList;
+ lldb::SBProcess * m_pProcess;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-list-changed-registers".
+// Gotchas: None.
+// Authors: Illya Rudkin 22/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataListRegisterChanged : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataListRegisterChanged( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataListRegisterChanged( void );
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-read-memory-bytes".
+// Gotchas: None.
+// Authors: Illya Rudkin 30/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataWriteMemoryBytes : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataWriteMemoryBytes( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataWriteMemoryBytes( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgAddr;
+ const CMIUtilString m_constStrArgContents;
+ const CMIUtilString m_constStrArgCount;
+ MIuint64 m_nAddr;
+ CMIUtilString m_strContents;
+ MIuint64 m_nCount;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-read-memory".
+// Not specified in MI spec but Eclipse gives *this command.
+// Gotchas: None.
+// Authors: Illya Rudkin 02/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdDataWriteMemory : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdDataWriteMemory( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataWriteMemory( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgOffset; // Not specified in MI spec but Eclipse gives this option.
+ const CMIUtilString m_constStrArgAddr; // Not specified in MI spec but Eclipse gives this option.
+ const CMIUtilString m_constStrArgD; // Not specified in MI spec but Eclipse gives this option.
+ const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option.
+ const CMIUtilString m_constStrArgContents; // Not specified in MI spec but Eclipse gives this option.
+ MIuint64 m_nAddr;
+ CMIUtilString m_strContents;
+ MIuint64 m_nCount;
+ MIuchar * m_pBufferMemory;
+}; \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdEnviro.cpp b/tools/lldb-mi/MICmdCmdEnviro.cpp
new file mode 100644
index 000000000000..b47327af9406
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdEnviro.cpp
@@ -0,0 +1,143 @@
+//===-- MICmdCmdEnviro.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdEnviro.cpp
+//
+// Overview: CMICmdCmdEnvironmentCd implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdEnviro.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValFile.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdEnvironmentCd constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdEnvironmentCd::CMICmdCmdEnvironmentCd( void )
+: m_constStrArgNamePathDir( "pathdir" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "environment-cd";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdEnvironmentCd::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdEnvironmentCd destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdEnvironmentCd::~CMICmdCmdEnvironmentCd( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdEnvironmentCd::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValFile( m_constStrArgNamePathDir, true, true ) ) );
+ CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdEnvironmentCd::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgPathDir, File, m_constStrArgNamePathDir );
+ const CMIUtilString & strWkDir( pArgPathDir->GetValue() );
+ CMICmnLLDBDebugger & rDbg( CMICmnLLDBDebugger::Instance() );
+ lldb::SBDebugger & rLldbDbg = rDbg.GetTheDebugger();
+ bool bOk = rLldbDbg.SetCurrentPlatformSDKRoot( strWkDir.c_str() );
+ if( bOk )
+ {
+ const CMIUtilString & rStrKeyWkDir( m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir );
+ if( !m_rLLDBDebugSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str() ) );
+ bOk = MIstatus::failure;
+ }
+ }
+ else
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()" ) );
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdEnvironmentCd::Acknowledge( void )
+{
+ const CMIUtilString & rStrKeyWkDir( m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir );
+ CMIUtilString strWkDir;
+ const bool bOk = m_rLLDBDebugSessionInfo.SharedDataRetrieve< CMIUtilString >( rStrKeyWkDir, strWkDir );
+ if( bOk )
+ {
+ const CMICmnMIValueConst miValueConst( strWkDir );
+ const CMICmnMIValueResult miValueResult( "path", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str() ) );
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdEnvironmentCd::CreateSelf( void )
+{
+ return new CMICmdCmdEnvironmentCd();
+}
diff --git a/tools/lldb-mi/MICmdCmdEnviro.h b/tools/lldb-mi/MICmdCmdEnviro.h
new file mode 100644
index 000000000000..efbe89238218
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdEnviro.h
@@ -0,0 +1,69 @@
+//===-- MICmdCmdEnviro.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdEnviro.h
+//
+// Overview: CMICmdCmdEnvironmentCd interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "environment-cd".
+// Gotchas: None.
+// Authors: Illya Rudkin 03/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdEnvironmentCd : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdEnvironmentCd( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdEnvironmentCd( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamePathDir;
+};
+
diff --git a/tools/lldb-mi/MICmdCmdExec.cpp b/tools/lldb-mi/MICmdCmdExec.cpp
new file mode 100644
index 000000000000..c0ec25d701b7
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdExec.cpp
@@ -0,0 +1,982 @@
+//===-- MICmdCmdExec.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdExec.cpp
+//
+// Overview: CMICmdCmdExecRun implementation.
+// CMICmdCmdExecContinue implementation.
+// CMICmdCmdExecNext implementation.
+// CMICmdCmdExecStep implementation.
+// CMICmdCmdExecNextInstruction implementation.
+// CMICmdCmdExecStepInstruction implementation.
+// CMICmdCmdExecFinish implementation.
+// CMICmdCmdExecInterrupt implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBCommandInterpreter.h>
+#include <lldb/API/SBProcess.h>
+#include <lldb/API/SBStream.h>
+#include "lldb/lldb-enumerations.h"
+
+// In-house headers:
+#include "MICmdCmdExec.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MIDriver.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmnStreamStdout.h"
+#include "MICmnMIOutOfBandRecord.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecRun constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecRun::CMICmdCmdExecRun( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-run";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecRun::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecRun destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecRun::~CMICmdCmdExecRun( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecRun::Execute( void )
+{
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBError error;
+ lldb::SBStream errMsg;
+ uint32_t launch_flags = lldb::LaunchFlags::eLaunchFlagDebug;
+ lldb::SBProcess process = rSessionInfo.m_lldbTarget.Launch (rSessionInfo.m_rLlldbListener,
+ nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, launch_flags, false, error);
+
+ if( (!process.IsValid()) || (error.Fail()) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str(), errMsg.GetData() ) );
+ return MIstatus::failure;
+ }
+
+ // Save the process in the session info
+ rSessionInfo.m_lldbProcess = process;
+
+ if( !CMIDriver::Instance().SetDriverStateRunningDebugging() )
+ {
+ const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SET_NEW_DRIVER_STATE ), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str() ) );
+ return MIstatus::failure;
+ }
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecRun::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ // Give the client '=thread-group-started,id="i1" pid="xyz"'
+ m_bHasResultRecordExtra = true;
+ const CMICmnMIValueConst miValueConst2( "i1" );
+ const CMICmnMIValueResult miValueResult2( "id", miValueConst2 );
+ const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
+ const CMICmnMIValueConst miValueConst( strPid );
+ const CMICmnMIValueResult miValueResult( "pid", miValueConst );
+ CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2 );
+ miOutOfBand.Add( miValueResult );
+ m_miResultRecordExtra = miOutOfBand.GetString();
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecRun::CreateSelf( void )
+{
+ return new CMICmdCmdExecRun();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecContinue constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecContinue::CMICmdCmdExecContinue( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-continue";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecContinue::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecContinue destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecContinue::~CMICmdCmdExecContinue( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecContinue::Execute( void )
+{
+ const MIchar * pCmd = "continue";
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( pCmd, m_lldbResult ); MIunused( rtn );
+
+
+ if( m_lldbResult.GetErrorSize() == 0 )
+ {
+ // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
+ if( !CMIDriver::Instance().SetDriverStateRunningDebugging() )
+ {
+ const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SET_NEW_DRIVER_STATE ), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+ else
+ {
+ // ToDo: Re-evaluate if this is required when application near finished as this is parsing LLDB error message
+ // which seems a hack and is code brittle
+ const MIchar * pLldbErr = m_lldbResult.GetError();
+ const CMIUtilString strLldbMsg( CMIUtilString( pLldbErr ).StripCREndOfLine() );
+ if( strLldbMsg == "error: Process must be launched." )
+ {
+ CMIDriver::Instance().SetExitApplicationFlag( true );
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecContinue::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecContinue::CreateSelf( void )
+{
+ return new CMICmdCmdExecContinue();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecNext constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecNext::CMICmdCmdExecNext( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgNumber( "number" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-next";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecNext::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecNext destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecNext::~CMICmdCmdExecNext( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNext::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNext::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "thread step-over" );
+ if( nThreadId != UINT64_MAX )
+ strCmd += CMIUtilString::Format( " %llu", nThreadId );
+ rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNext::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecNext::CreateSelf( void )
+{
+ return new CMICmdCmdExecNext();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecStep constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecStep::CMICmdCmdExecStep( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgNumber( "number" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-step";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecStep::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecStep destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecStep::~CMICmdCmdExecStep( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStep::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStep::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "thread step-in" );
+ if( nThreadId != UINT64_MAX )
+ strCmd += CMIUtilString::Format( " %llu", nThreadId );
+ rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStep::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecStep::CreateSelf( void )
+{
+ return new CMICmdCmdExecStep();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecNextInstruction constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgNumber( "number" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-next-instruction";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecNextInstruction::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecNextInstruction destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecNextInstruction::~CMICmdCmdExecNextInstruction( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNextInstruction::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNextInstruction::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "thread step-inst-over" );
+ if( nThreadId != UINT64_MAX )
+ strCmd += CMIUtilString::Format( " %llu", nThreadId );
+ rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecNextInstruction::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecNextInstruction::CreateSelf( void )
+{
+ return new CMICmdCmdExecNextInstruction();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecStepInstruction constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgNumber( "number" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-step-instruction";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecStepInstruction::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecStepInstruction destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecStepInstruction::~CMICmdCmdExecStepInstruction( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStepInstruction::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStepInstruction::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "thread step-inst" );
+ if( nThreadId != UINT64_MAX )
+ strCmd += CMIUtilString::Format( " %llu", nThreadId );
+ rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecStepInstruction::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecStepInstruction::CreateSelf( void )
+{
+ return new CMICmdCmdExecStepInstruction();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecFinish constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecFinish::CMICmdCmdExecFinish( void )
+: m_constStrArgThread( "thread" )
+, m_constStrArgFrame( "frame" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-finish";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecFinish::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecFinish destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecFinish::~CMICmdCmdExecFinish( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecFinish::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecFinish::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "thread step-out" );
+ if( nThreadId != UINT64_MAX )
+ strCmd += CMIUtilString::Format( " %llu", nThreadId );
+ rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecFinish::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecFinish::CreateSelf( void )
+{
+ return new CMICmdCmdExecFinish();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecInterrupt constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-interrupt";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecInterrupt::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecInterrupt destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecInterrupt::~CMICmdCmdExecInterrupt( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecInterrupt::Execute( void )
+{
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
+ CMIUtilString strCmd( "process interrupt" );
+ const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false ); MIunused( status );
+
+ // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
+ if( !CMIDriver::Instance().SetDriverStateRunningNotDebugging() )
+ {
+ const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
+ SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SET_NEW_DRIVER_STATE ), strCmd.c_str(), rErrMsg.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdExecInterrupt::Acknowledge( void )
+{
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
+ const CMICmnMIValueResult miValueResult( "message", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdExecInterrupt::CreateSelf( void )
+{
+ return new CMICmdCmdExecInterrupt();
+}
+
diff --git a/tools/lldb-mi/MICmdCmdExec.h b/tools/lldb-mi/MICmdCmdExec.h
new file mode 100644
index 000000000000..a712b23ca5e0
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdExec.h
@@ -0,0 +1,310 @@
+//===-- MICmdCmdExec.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdExec.h
+//
+// Overview: CMICmdCmdExecRun interface.
+// CMICmdCmdExecContinue interface.
+// CMICmdCmdExecNext interface.
+// CMICmdCmdExecStep interface.
+// CMICmdCmdExecNextInstruction interface.
+// CMICmdCmdExecStepInstruction interface.
+// CMICmdCmdExecFinish interface.
+// CMICmdCmdExecInterrupt interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <lldb/API/SBCommandReturnObject.h>
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-run".
+// Gotchas: None.
+// Authors: Illya Rudkin 07/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecRun : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecRun( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecRun( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-continue".
+// Gotchas: None.
+// Authors: Illya Rudkin 07/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecContinue : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecContinue( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecContinue( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-next".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecNext : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecNext( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecNext( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-step".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecStep : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecStep( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecStep( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-next-instruction".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecNextInstruction : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecNextInstruction( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecNextInstruction( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-step-instruction".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecStepInstruction : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecStepInstruction( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecStepInstruction( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-finish".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecFinish : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecFinish( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecFinish( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
+};
+
+// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-interrupt".
+// Gotchas: Using Eclipse this command is injected into the command system when a
+// SIGINT signal is received while running an inferior program.
+// Authors: Illya Rudkin 03/06/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecInterrupt : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdExecInterrupt( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecInterrupt( void );
+
+// Attributes:
+private:
+ lldb::SBCommandReturnObject m_lldbResult;
+};
+
diff --git a/tools/lldb-mi/MICmdCmdFile.cpp b/tools/lldb-mi/MICmdCmdFile.cpp
new file mode 100644
index 000000000000..1d0b494362ce
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdFile.cpp
@@ -0,0 +1,184 @@
+//===-- MICmdCmdFile.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdFile.cpp
+//
+// Overview: CMICmdCmdFileExecAndSymbols implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBStream.h>
+
+// In-house headers:
+#include "MICmdCmdFile.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MIUtilFileStd.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValOptionLong.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdFileExecAndSymbols constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdFileExecAndSymbols::CMICmdCmdFileExecAndSymbols( void )
+: m_constStrArgNameFile( "file" )
+, m_constStrArgThreadGrp( "thread-group" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "file-exec-and-symbols";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdFileExecAndSymbols::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdFileExecAndSymbols destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdFileExecAndSymbols::~CMICmdCmdFileExecAndSymbols( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdFileExecAndSymbols::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValFile( m_constStrArgNameFile, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Synopsis: -file-exec-and-symbols file
+// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-File-Commands.html#GDB_002fMI-File-Commands
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdFileExecAndSymbols::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgNamedFile, File, m_constStrArgNameFile );
+ CMICmdArgValFile * pArgFile = static_cast< CMICmdArgValFile * >( pArgNamedFile );
+ const CMIUtilString & strExeFilePath( pArgFile->GetValue() );
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
+ lldb::SBError error;
+ const MIchar * pTargetTriple = nullptr; // Let LLDB discover the triple required
+ const MIchar * pTargetPlatformName = "";
+ const bool bAddDepModules = false;
+ lldb::SBTarget target = rDbgr.CreateTarget( strExeFilePath.c_str(), pTargetTriple, pTargetPlatformName, bAddDepModules, error );
+ CMIUtilString strWkDir;
+ const CMIUtilString & rStrKeyWkDir( rSessionInfo.m_constStrSharedDataKeyWkDir );
+ if( !rSessionInfo.SharedDataRetrieve< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
+ {
+ strWkDir = CMIUtilFileStd().StripOffFileName( strExeFilePath );
+ if( !rSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+ if( !rDbgr.SetCurrentPlatformSDKRoot( strWkDir.c_str() ) )
+ {
+
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()" ) );
+ return MIstatus::failure;
+ }
+ lldb::SBStream err;
+ if( error.Fail() )
+ {
+ const bool bOk = error.GetDescription( err ); MIunused( bOk );
+ }
+ if( !target.IsValid() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET ), m_cmdData.strMiCmd.c_str(), strExeFilePath.c_str(), err.GetData() ) );
+ return MIstatus::failure;
+ }
+ if( error.Fail() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_CREATE_TARGET ), m_cmdData.strMiCmd.c_str(), err.GetData() ) );
+ return MIstatus::failure;
+ }
+
+ rSessionInfo.m_lldbTarget = target;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdFileExecAndSymbols::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdFileExecAndSymbols::CreateSelf( void )
+{
+ return new CMICmdCmdFileExecAndSymbols();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: If the MI Driver is not operating via a client i.e. Eclipse but say operating
+// on a executable passed in as a argument to the drive then what should the driver
+// do on a command failing? Either continue operating or exit the application.
+// Override this function where a command failure cannot allow the driver to
+// continue operating.
+// Type: Overridden.
+// Args: None.
+// Return: bool - True = Fatal if command fails, false = can continue if command fails.
+// Throws: None.
+//--
+bool CMICmdCmdFileExecAndSymbols::GetExitAppOnCommandFailure( void ) const
+{
+ return true;
+} \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdFile.h b/tools/lldb-mi/MICmdCmdFile.h
new file mode 100644
index 000000000000..a80a313ea7b5
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdFile.h
@@ -0,0 +1,71 @@
+//===-- MICmdCmdFile.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdFile.h
+//
+// Overview: CMICmdCmdFileExecAndSymbols interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "file-exec-and-symbols".
+// This command does not follow the MI documentation exactly.
+// Gotchas: None.
+// Authors: Illya Rudkin 25/02/2014.
+// Changes: None.
+//--
+class CMICmdCmdFileExecAndSymbols : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdFileExecAndSymbols( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdFileExecAndSymbols( void );
+ virtual bool GetExitAppOnCommandFailure( void ) const;
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNameFile;
+ const CMIUtilString m_constStrArgThreadGrp; // Not handled by *this command. Not specified in MI spec but Eclipse gives this option sometimes
+};
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.cpp b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
new file mode 100644
index 000000000000..62bb1f280bc3
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
@@ -0,0 +1,232 @@
+//===-- MICmdCmdGdbInfo.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbInfo.cpp
+//
+// Overview: CMICmdCmdGdbInfo implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third party headers:
+#include <lldb/API/SBCommandReturnObject.h>
+
+// In-house headers:
+#include "MICmdCmdGdbInfo.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmdArgValString.h"
+#include "MICmnStreamStdout.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+
+// Instantiations:
+const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn =
+{
+ { "sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary }
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbInfo constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbInfo::CMICmdCmdGdbInfo( void )
+: m_constStrArgNamedPrint( "print" )
+, m_bPrintFnRecognised( true )
+, m_bPrintFnSuccessful( false )
+, m_strPrintFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "info";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbInfo destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbInfo::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedPrint, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbInfo::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgPrint, String, m_constStrArgNamedPrint );
+ const CMIUtilString & rPrintRequest( pArgPrint->GetValue() );
+
+ FnPrintPtr pPrintRequestFn = nullptr;
+ if( !GetPrintFn( rPrintRequest, pPrintRequestFn ) )
+ {
+ m_strPrintFnName = rPrintRequest;
+ m_bPrintFnRecognised = false;
+ return MIstatus::success;
+ }
+
+ m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbInfo::Acknowledge( void )
+{
+ if( !m_bPrintFnRecognised )
+ {
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strPrintFnName.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ if( m_bPrintFnSuccessful )
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strPrintFnError.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdGdbInfo::CreateSelf( void )
+{
+ return new CMICmdCmdGdbInfo();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the print function's pointer for the matching print request.
+// Type: Method.
+// Args: vrPrintFnName - (R) The info requested.
+// vrwpFn - (W) The print function's pointer of the function to carry out
+// Return: bool - True = Print request is implemented, false = not found.
+// Throws: None.
+//--
+bool CMICmdCmdGdbInfo::GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const
+{
+ vrwpFn = nullptr;
+
+ const MapPrintFnNameToPrintFn_t::const_iterator it = ms_mapPrintFnNameToPrintFn.find( vrPrintFnName );
+ if( it != ms_mapPrintFnNameToPrintFn.end() )
+ {
+ vrwpFn = (*it).second;
+ return true;
+ }
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the request to prepare and send back information
+// asked for.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbInfo::PrintFnSharedLibrary( void )
+{
+ CMICmnStreamStdout & rStdout = CMICmnStreamStdout::Instance();
+ bool bOk = rStdout.TextToStdout( "~\"From To Syms Read Shared Object Library\"" );
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
+ const MIuint nModules = rTarget.GetNumModules();
+ for( MIuint i = 0; bOk && (i < nModules); i++ )
+ {
+ lldb::SBModule module = rTarget.GetModuleAtIndex( i );
+ if( module.IsValid() )
+ {
+ const CMIUtilString strModuleFilePath( module.GetFileSpec().GetDirectory() );
+ const CMIUtilString strModuleFileName( module.GetFileSpec().GetFilename() );
+ const CMIUtilString strModuleFullPath( CMIUtilString::Format( "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str() ) );
+ const CMIUtilString strHasSymbols = (module.GetNumSymbols() > 0) ? "Yes" : "No";
+ lldb::addr_t addrLoadS = 0xffffffff;
+ lldb::addr_t addrLoadSize = 0;
+ bool bHaveAddrLoad = false;
+ const MIuint nSections = module.GetNumSections();
+ for( MIuint j = 0; j < nSections; j++ )
+ {
+ lldb::SBSection section = module.GetSectionAtIndex( j );
+ lldb::addr_t addrLoad = section.GetLoadAddress( rTarget );
+ if( addrLoad != (lldb::addr_t) -1 )
+ {
+ if( !bHaveAddrLoad )
+ {
+ bHaveAddrLoad = true;
+ addrLoadS = addrLoad;
+ }
+
+ addrLoadSize += section.GetByteSize();
+ }
+ }
+ bOk = bOk && rStdout.TextToStdout( CMIUtilString::Format( "~\"0x%08x\t0x%08x\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize, strHasSymbols.c_str(), strModuleFullPath.c_str() ) );
+ }
+ }
+
+ return bOk;
+}
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.h b/tools/lldb-mi/MICmdCmdGdbInfo.h
new file mode 100644
index 000000000000..3fa920669416
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbInfo.h
@@ -0,0 +1,93 @@
+//===-- MICmdCmdGdbInfo.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbInfo.h
+//
+// Overview: CMICmdCmdGdbInfo interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <map>
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements GDB command "info".
+// The design of matching the info request to a request action (or
+// command) is very simple. The request function which carries out
+// the task of information gathering and printing to stdout is part of
+// *this class. Should the request function become more complicated then
+// that request should really reside in a command type class. Then this
+// class instantiates a request info command for a matching request. The
+// design/code of *this class then does not then become bloated. Use a
+// lightweight version of the current MI command system.
+// Gotchas: None.
+// Authors: Illya Rudkin 05/06/2014.
+// Changes: None.
+//--
+class CMICmdCmdGdbInfo : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdGdbInfo( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdGdbInfo( void );
+
+// Typedefs:
+private:
+ typedef bool (CMICmdCmdGdbInfo::*FnPrintPtr)();
+ typedef std::map< CMIUtilString, FnPrintPtr > MapPrintFnNameToPrintFn_t;
+
+// Methods:
+private:
+ bool GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const;
+ bool PrintFnSharedLibrary( void );
+
+// Attributes:
+private:
+ const static MapPrintFnNameToPrintFn_t ms_mapPrintFnNameToPrintFn;
+ //
+ const CMIUtilString m_constStrArgNamedPrint;
+ bool m_bPrintFnRecognised; // True = This command has a function with a name that matches the Print argument, false = not found
+ bool m_bPrintFnSuccessful; // True = The print function completed its task ok, false = function failed for some reason
+ CMIUtilString m_strPrintFnName;
+ CMIUtilString m_strPrintFnError;
+}; \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.cpp b/tools/lldb-mi/MICmdCmdGdbSet.cpp
new file mode 100644
index 000000000000..a256ee2e2ca1
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbSet.cpp
@@ -0,0 +1,260 @@
+//===-- MICmdCmdGdbSet.cpp ------- -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbSet.cpp
+//
+// Overview: CMICmdCmdGdbSet implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdGdbSet.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+
+// Instantiations:
+const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr =
+{
+ // { "target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync }, // Example code if need to implement GDB set other options
+ // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, // Example code if need to implement GDB set other options
+ { "solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath },
+ { "fallback", &CMICmdCmdGdbSet::OptionFnFallback }
+};
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbSet constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbSet::CMICmdCmdGdbSet( void )
+: m_constStrArgNamedThreadGrp( "thread-group" )
+, m_constStrArgNamedGdbOption( "option" )
+, m_bGdbOptionRecognised( true )
+, m_bGdbOptionFnSuccessful( false )
+, m_bGbbOptionFnHasError( false )
+, m_strGdbOptionFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "gdb-set";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbSet destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbSet::~CMICmdCmdGdbSet( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringAnything ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption );
+ const CMICmdArgValListBase::VecArgObjPtr_t & rVecWords( pArgGdbOption->GetExpectedOptions() );
+
+ // Get the gdb-set option to carry out
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
+ const CMICmdArgValString * pOption = static_cast< const CMICmdArgValString * >( *it );
+ const CMIUtilString strOption( pOption->GetValue() );
+ ++it;
+
+ // Retrieve the parameter(s) for the option
+ CMIUtilString::VecString_t vecWords;
+ while( it != rVecWords.end() )
+ {
+ const CMICmdArgValString * pWord = static_cast< const CMICmdArgValString * >( *it );
+ vecWords.push_back( pWord->GetValue() );
+
+ // Next
+ ++it;
+ }
+
+ FnGdbOptionPtr pPrintRequestFn = nullptr;
+ if( !GetOptionFn( strOption, pPrintRequestFn ) )
+ {
+ // For unimplemented option handlers, fallback on a generic handler
+ // ToDo: Remove this when ALL options have been implemented
+ if( !GetOptionFn( "fallback", pPrintRequestFn ) )
+ {
+ m_bGdbOptionRecognised = false;
+ m_strGdbOptionName = "fallback"; // This would be the strOption name
+ return MIstatus::success;
+ }
+ }
+
+ m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))( vecWords );
+ if( !m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError )
+ return MIstatus::failure;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::Acknowledge( void )
+{
+ if( !m_bGdbOptionRecognised )
+ {
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strGdbOptionName.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ if( m_bGdbOptionFnSuccessful )
+ {
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strGdbOptionFnError.c_str() ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdGdbSet::CreateSelf( void )
+{
+ return new CMICmdCmdGdbSet();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the print function's pointer for the matching print request.
+// Type: Method.
+// Args: vrPrintFnName - (R) The info requested.
+// vrwpFn - (W) The print function's pointer of the function to carry out
+// Return: bool - True = Print request is implemented, false = not found.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::GetOptionFn( const CMIUtilString & vrPrintFnName, FnGdbOptionPtr & vrwpFn ) const
+{
+ vrwpFn = nullptr;
+
+ const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it = ms_mapGdbOptionNameToFnGdbOptionPtr.find( vrPrintFnName );
+ if( it != ms_mapGdbOptionNameToFnGdbOptionPtr.end() )
+ {
+ vrwpFn = (*it).second;
+ return true;
+ }
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB set option 'solib-search-path' to prepare
+// and send back information asked for.
+// Type: Method.
+// Args: vrWords - (R) List of additional parameters used by this option.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::OptionFnSolibSearchPath( const CMIUtilString::VecString_t & vrWords )
+{
+ // Check we have at least one argument
+ if( vrWords.size() < 1 )
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = MIRSRC( IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH );
+ return MIstatus::failure;
+ }
+ const CMIUtilString & rStrValSolibPath( vrWords[ 0 ] );
+
+ // Add 'solib-search-path' to the shared data list
+ const CMIUtilString & rStrKeySolibPath( m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath );
+ if( !m_rLLDBDebugSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeySolibPath, rStrValSolibPath ) )
+ {
+ m_bGbbOptionFnHasError = false;
+ SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeySolibPath.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB set option to prepare and send back information
+// asked for.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbSet::OptionFnFallback( const CMIUtilString::VecString_t & vrWords )
+{
+ MIunused( vrWords );
+
+ // Do nothing - intentional. This is a fallback temporary action function to do nothing.
+ // This allows the search for gdb-set options to always suceed when the option is not
+ // found (implemented).
+
+ return MIstatus::success;
+}
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.h b/tools/lldb-mi/MICmdCmdGdbSet.h
new file mode 100644
index 000000000000..24b54557bf37
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbSet.h
@@ -0,0 +1,96 @@
+//===-- MICmdCmdGdbSet.h ------------- ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbSet.h
+//
+// Overview: CMICmdCmdGdbSet interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "gdb-set".
+// This command does not follow the MI documentation exactly. While *this
+// command is implemented it does not do anything with the gdb-set
+// variable past in.
+// The design of matching the info request to a request action (or
+// command) is very simple. The request function which carries out
+// the task of information gathering and printing to stdout is part of
+// *this class. Should the request function become more complicated then
+// that request should really reside in a command type class. Then this
+// class instantiates a request info command for a matching request. The
+// design/code of *this class then does not then become bloated. Use a
+// lightweight version of the current MI command system.
+// Gotchas: None.
+// Authors: Illya Rudkin 03/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdGdbSet : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdGdbSet( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdGdbSet( void );
+
+// Typedefs:
+private:
+ typedef bool (CMICmdCmdGdbSet::*FnGdbOptionPtr)( const CMIUtilString::VecString_t & vrWords );
+ typedef std::map< CMIUtilString, FnGdbOptionPtr > MapGdbOptionNameToFnGdbOptionPtr_t;
+
+// Methods:
+private:
+ bool GetOptionFn( const CMIUtilString & vrGdbOptionName, FnGdbOptionPtr & vrwpFn ) const;
+ bool OptionFnSolibSearchPath( const CMIUtilString::VecString_t & vrWords );
+ bool OptionFnFallback( const CMIUtilString::VecString_t & vrWords );
+
+// Attributes:
+private:
+ const static MapGdbOptionNameToFnGdbOptionPtr_t ms_mapGdbOptionNameToFnGdbOptionPtr;
+ //
+ const CMIUtilString m_constStrArgNamedThreadGrp;
+ const CMIUtilString m_constStrArgNamedGdbOption;
+ bool m_bGdbOptionRecognised; // True = This command has a function with a name that matches the Print argument, false = not found
+ bool m_bGdbOptionFnSuccessful; // True = The print function completed its task ok, false = function failed for some reason
+ bool m_bGbbOptionFnHasError; // True = The option function has an error condition (not the command!), false = option function ok.
+ CMIUtilString m_strGdbOptionName;
+ CMIUtilString m_strGdbOptionFnError;
+}; \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.cpp b/tools/lldb-mi/MICmdCmdGdbThread.cpp
new file mode 100644
index 000000000000..09bd053a65e1
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbThread.cpp
@@ -0,0 +1,100 @@
+//===-- MICmdCmdGdbThread.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbThread.cpp
+//
+// Overview: CMICmdCmdGdbThread implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdGdbThread.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbThread constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbThread::CMICmdCmdGdbThread( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "thread";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdGdbThread::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdThread destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbThread::~CMICmdCmdGdbThread( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbThread::Execute( void )
+{
+ // Do nothing
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbThread::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdGdbThread::CreateSelf( void )
+{
+ return new CMICmdCmdGdbThread();
+} \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.h b/tools/lldb-mi/MICmdCmdGdbThread.h
new file mode 100644
index 000000000000..29c1361b4cf4
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbThread.h
@@ -0,0 +1,61 @@
+//===-- MICmdCmdGdbThread.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdGdbThread.h
+//
+// Overview: CMICmdCmdGdbThread interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements GDB command "thread".
+// Gotchas: None.
+// Authors: Illya Rudkin 25/02/2014.
+// Changes: None.
+//--
+class CMICmdCmdGdbThread : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdGdbThread( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdGdbThread( void );
+}; \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.cpp b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
new file mode 100644
index 000000000000..b09f585598a4
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
@@ -0,0 +1,588 @@
+//===-- MICmdCmdMiscellanous.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdMiscellanous.cpp
+//
+// Overview: CMICmdCmdGdbExit implementation.
+// CMICmdCmdListThreadGroups implementation.
+// CMICmdCmdInterpreterExec implementation.
+// CMICmdCmdInferiorTtySet implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBCommandInterpreter.h>
+#include <lldb/API/SBThread.h>
+
+// In-house headers:
+#include "MICmdCmdMiscellanous.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIOutOfBandRecord.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MIDriverBase.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmnStreamStdout.h"
+#include "MICmnStreamStderr.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbExit constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbExit::CMICmdCmdGdbExit( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "gdb-exit";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdGdbExit::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbExit destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbExit::~CMICmdCmdGdbExit( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbExit::Execute( void )
+{
+ CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag( true );
+ const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.m_lldbProcess.Detach();
+ // Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdGdbExit::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Exit );
+ m_miResultRecord = miRecordResult;
+
+ // Prod the client i.e. Eclipse with out-of-band results to help it 'continue' because it is using LLDB debugger
+ // Give the client '=thread-group-exited,id="i1"'
+ m_bHasResultRecordExtra = true;
+ const CMICmnMIValueConst miValueConst2( "i1" );
+ const CMICmnMIValueResult miValueResult2( "id", miValueConst2 );
+ const CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult2 );
+ m_miResultRecordExtra = miOutOfBand.GetString();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdGdbExit::CreateSelf( void )
+{
+ return new CMICmdCmdGdbExit();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdListThreadGroups constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdListThreadGroups::CMICmdCmdListThreadGroups( void )
+: m_bIsI1( false )
+, m_bHaveArgOption( false )
+, m_bHaveArgRecurse( false )
+, m_constStrArgNamedAvailable( "available" )
+, m_constStrArgNamedRecurse( "recurse" )
+, m_constStrArgNamedGroup( "group" )
+, m_constStrArgNamedThreadGroup( "i1" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "list-thread-groups";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdListThreadGroups::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdListThreadGroups destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdListThreadGroups::~CMICmdCmdListThreadGroups( void )
+{
+ m_vecMIValueTuple.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdListThreadGroups::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedAvailable, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedRecurse, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedGroup, false, true, CMICmdArgValListBase::eArgValType_Number ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValThreadGrp( m_constStrArgNamedThreadGroup, false, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Synopis: -list-thread-groups [ --available ] [ --recurse 1 ] [ group ... ]
+// This command does not follow the MI documentation exactly. Has an extra
+// argument "i1" to handle.
+// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdListThreadGroups::Execute( void )
+{
+ if( m_setCmdArgs.IsArgContextEmpty() )
+ // No options so "top level thread groups"
+ return MIstatus::success;
+
+ CMICMDBASE_GETOPTION( pArgAvailable, OptionLong, m_constStrArgNamedAvailable );
+ CMICMDBASE_GETOPTION( pArgRecurse, OptionLong, m_constStrArgNamedRecurse );
+ CMICMDBASE_GETOPTION( pArgThreadGroup, ThreadGrp, m_constStrArgNamedThreadGroup );
+
+ // Got some options so "threads"
+ if( pArgAvailable->GetFound() )
+ {
+ if( pArgRecurse->GetFound() )
+ {
+ m_bHaveArgRecurse = true;
+ return MIstatus::success;
+ }
+
+ m_bHaveArgOption = true;
+ return MIstatus::success;
+ }
+ // "i1" as first argument (pos 0 of possible arg)
+ if( !pArgThreadGroup->GetFound() )
+ return MIstatus::success;
+ m_bIsI1 = true;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+
+ // Note do not check for rProcess is IsValid(), continue
+
+ m_vecMIValueTuple.clear();
+ const MIuint nThreads = rProcess.GetNumThreads();
+ for( MIuint i = 0; i < nThreads; i++ )
+ {
+ // GetThreadAtIndex() uses a base 0 index
+ // GetThreadByIndexID() uses a base 1 index
+ lldb::SBThread thread = rProcess.GetThreadAtIndex( i );
+
+ if( thread.IsValid() )
+ {
+ CMICmnMIValueTuple miTuple;
+ if( !rSessionInfo.MIResponseFormThreadInfo2( m_cmdData, thread, miTuple ) )
+ return MIstatus::failure;
+
+ m_vecMIValueTuple.push_back( miTuple );
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdListThreadGroups::Acknowledge( void )
+{
+ if( m_bHaveArgOption )
+ {
+ if( m_bHaveArgRecurse )
+ {
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst1( "i1" );
+ const CMICmnMIValueResult miValueResult1( "id", miValueConst1 );
+ CMICmnMIValueTuple miTuple( miValueResult1 );
+
+ const CMICmnMIValueConst miValueConst2( "process" );
+ const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
+ miTuple.Add( miValueResult2 );
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ if (rSessionInfo.m_lldbProcess.IsValid ())
+ {
+ const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
+ const CMICmnMIValueConst miValueConst3( strPid );
+ const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 );
+ miTuple.Add( miValueResult3 );
+ }
+
+ const CMICmnMIValueConst miValueConst4( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
+ const CMICmnMIValueResult miValueResult4( "num_children", miValueConst4 );
+ miTuple.Add( miValueResult4 );
+
+ const CMICmnMIValueConst miValueConst5( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
+ const CMICmnMIValueResult miValueResult5( "cores", miValueConst5 );
+ miTuple.Add( miValueResult5 );
+
+ const CMICmnMIValueList miValueList( miTuple );
+ const CMICmnMIValueResult miValueResult6( "groups", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ if( !m_bIsI1 )
+ {
+ const CMICmnMIValueConst miValueConst1( "i1" );
+ const CMICmnMIValueResult miValueResult1( "id", miValueConst1 );
+ CMICmnMIValueTuple miTuple( miValueResult1 );
+
+ const CMICmnMIValueConst miValueConst2( "process" );
+ const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
+ miTuple.Add( miValueResult2 );
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ if (rSessionInfo.m_lldbProcess.IsValid ())
+ {
+ const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
+ const CMICmnMIValueConst miValueConst3( strPid );
+ const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 );
+ miTuple.Add( miValueResult3 );
+ }
+
+ if (rSessionInfo.m_lldbTarget.IsValid ())
+ {
+ lldb::SBTarget & rTrgt = rSessionInfo.m_lldbTarget;
+ const MIchar * pDir = rTrgt.GetExecutable().GetDirectory();
+ const MIchar * pFileName = rTrgt.GetExecutable().GetFilename();
+ const CMIUtilString strFile( CMIUtilString::Format( "%s/%s", pDir, pFileName ) );
+ const CMICmnMIValueConst miValueConst4( strFile );
+ const CMICmnMIValueResult miValueResult4( "executable", miValueConst4 );
+ miTuple.Add( miValueResult4 );
+ }
+
+ const CMICmnMIValueList miValueList( miTuple );
+ const CMICmnMIValueResult miValueResult5( "groups", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // Build up a list of thread information from tuples
+ VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
+ if( it == m_vecMIValueTuple.end() )
+ {
+ const CMICmnMIValueConst miValueConst( "[]" );
+ const CMICmnMIValueResult miValueResult( "threads", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ CMICmnMIValueList miValueList( *it );
+ ++it;
+ while( it != m_vecMIValueTuple.end() )
+ {
+ const CMICmnMIValueTuple & rTuple( *it );
+ miValueList.Add( rTuple );
+
+ // Next
+ ++it;
+ }
+
+ const CMICmnMIValueResult miValueResult( "threads", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdListThreadGroups::CreateSelf( void )
+{
+ return new CMICmdCmdListThreadGroups();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdInterpreterExec constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec( void )
+: m_constStrArgNamedInterpreter( "intepreter" )
+, m_constStrArgNamedCommand( "command" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "interpreter-exec";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdInterpreterExec::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdInterpreterExec destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdInterpreterExec::~CMICmdCmdInterpreterExec( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdInterpreterExec::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedInterpreter, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedCommand, true, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdInterpreterExec::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgInterpreter, String, m_constStrArgNamedInterpreter );
+ CMICMDBASE_GETOPTION( pArgCommand, String, m_constStrArgNamedCommand );
+
+ // Handle the interpreter parameter by do nothing on purpose (set to 'handled' in
+ // the arg definition above)
+ const CMIUtilString & rStrInterpreter( pArgInterpreter->GetValue() ); MIunused( rStrInterpreter );
+
+ const CMIUtilString & rStrCommand( pArgCommand->GetValue() );
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( rStrCommand.c_str(), m_lldbResult, true ); MIunused( rtn );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdInterpreterExec::Acknowledge( void )
+{
+ if( m_lldbResult.GetOutputSize() > 0 )
+ {
+ CMIUtilString strMsg( m_lldbResult.GetOutput() );
+ strMsg = strMsg.StripCREndOfLine();
+ CMICmnStreamStdout::TextToStdout( strMsg );
+
+ // Send the LLDB result message to console so the user can see the result of the
+ // command they typed. It is not necessary an error message.
+ CMICmnStreamStderr::LLDBMsgToConsole( strMsg );
+ }
+ if( m_lldbResult.GetErrorSize() > 0 )
+ {
+ CMIUtilString strMsg( m_lldbResult.GetError() );
+ strMsg = strMsg.StripCREndOfLine();
+ CMICmnStreamStderr::LLDBMsgToConsole( strMsg );
+
+ // Send LLDB's error message to the MI Driver's Log file
+ CMICmnStreamStdout::TextToStdout( strMsg );
+ }
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdInterpreterExec::CreateSelf( void )
+{
+ return new CMICmdCmdInterpreterExec();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdInferiorTtySet constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdInferiorTtySet::CMICmdCmdInferiorTtySet( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "inferior-tty-set";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdInferiorTtySet::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdInferiorTtySet destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdInferiorTtySet::~CMICmdCmdInferiorTtySet( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdInferiorTtySet::Execute( void )
+{
+ // Do nothing
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdInferiorTtySet::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdInferiorTtySet::CreateSelf( void )
+{
+ return new CMICmdCmdInferiorTtySet();
+}
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.h b/tools/lldb-mi/MICmdCmdMiscellanous.h
new file mode 100644
index 000000000000..ea71f1233418
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.h
@@ -0,0 +1,175 @@
+//===-- MICmdCmdMiscellanous.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdMiscellanous.h
+//
+// Overview: CMICmdCmdGdbExit interface.
+// CMICmdCmdListThreadGroups interface.
+// CMICmdCmdInterpreterExec interface.
+// CMICmdCmdInferiorTtySet interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// Third party headers:
+#include <lldb/API/SBCommandReturnObject.h>
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "gdb-exit".
+// Gotchas: None.
+// Authors: Illya Rudkin 04/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdGdbExit : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdGdbExit( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdGdbExit( void );
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "list-thread-groups".
+// This command does not follow the MI documentation exactly.
+// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
+// Gotchas: None.
+// Authors: Illya Rudkin 06/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdListThreadGroups : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdListThreadGroups( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdListThreadGroups( void );
+
+// Typedefs:
+private:
+ typedef std::vector< CMICmnMIValueTuple > VecMIValueTuple_t;
+
+// Attributes:
+private:
+ bool m_bIsI1; // True = Yes command argument equal "i1", false = no match
+ bool m_bHaveArgOption; // True = Yes "--available" present, false = not found
+ bool m_bHaveArgRecurse; // True = Yes command argument "--recurse", false = no found
+ VecMIValueTuple_t m_vecMIValueTuple;
+ const CMIUtilString m_constStrArgNamedAvailable;
+ const CMIUtilString m_constStrArgNamedRecurse;
+ const CMIUtilString m_constStrArgNamedGroup;
+ const CMIUtilString m_constStrArgNamedThreadGroup;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "interpreter-exec".
+// Gotchas: None.
+// Authors: Illya Rudkin 16/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdInterpreterExec : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdInterpreterExec( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdInterpreterExec( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedInterpreter;
+ const CMIUtilString m_constStrArgNamedCommand;
+ lldb::SBCommandReturnObject m_lldbResult;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "inferior-tty-set".
+// Gotchas: None.
+// Authors: Illya Rudkin 22/07/2014.
+// Changes: None.
+//--
+class CMICmdCmdInferiorTtySet : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdInferiorTtySet( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdInferiorTtySet( void );
+}; \ No newline at end of file
diff --git a/tools/lldb-mi/MICmdCmdStack.cpp b/tools/lldb-mi/MICmdCmdStack.cpp
new file mode 100644
index 000000000000..5f5b355758c4
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdStack.cpp
@@ -0,0 +1,634 @@
+//===-- MICmdCmdStack.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdStack.cpp
+//
+// Overview: CMICmdCmdStackInfoDepth implementation.
+// CMICmdCmdStackListFrames implementation.
+// CMICmdCmdStackListArguments implementation.
+// CMICmdCmdStackListLocals implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBThread.h>
+
+// In-house headers:
+#include "MICmdCmdStack.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIOutOfBandRecord.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackInfoDepth constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth( void )
+: m_nThreadFrames( 0 )
+, m_constStrArgThread( "thread" )
+, m_constStrArgMaxDepth( "max-depth" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-info-depth";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackInfoDepth destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoDepth::~CMICmdCmdStackInfoDepth( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackInfoDepth::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMaxDepth, false, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackInfoDepth::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgMaxDepth, Number, m_constStrArgMaxDepth );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
+ m_nThreadFrames = thread.GetNumFrames();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackInfoDepth::Acknowledge( void )
+{
+ const CMIUtilString strDepth( CMIUtilString::Format( "%d", m_nThreadFrames ) );
+ const CMICmnMIValueConst miValueConst( strDepth );
+ const CMICmnMIValueResult miValueResult( "depth", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdStackInfoDepth::CreateSelf( void )
+{
+ return new CMICmdCmdStackInfoDepth();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListFrames constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListFrames::CMICmdCmdStackListFrames( void )
+: m_nThreadFrames( 0 )
+, m_constStrArgThread( "thread" )
+, m_constStrArgFrameLow( "low-frame" )
+, m_constStrArgFrameHigh( "high-frame" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-frames";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListFrames destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListFrames::~CMICmdCmdStackListFrames( void )
+{
+ m_vecMIValueResult.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListFrames::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameLow, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameHigh, false, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListFrames::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgFrameLow, Number, m_constStrArgFrameLow );
+ CMICMDBASE_GETOPTION( pArgFrameHigh, Number, m_constStrArgFrameHigh );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ // Frame low and high options are not mandatory
+ MIuint nFrameHigh = pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT64_MAX;
+ const MIuint nFrameLow = pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
+ MIuint nThreadFrames = thread.GetNumFrames();
+
+ // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in the min calc as the arg
+ // is not an index, but a frame id value.
+ if( nFrameHigh < UINT32_MAX )
+ {
+ nFrameHigh++;
+ nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
+ }
+
+ m_nThreadFrames = nThreadFrames;
+ if( nThreadFrames == 0 )
+ return MIstatus::success;
+
+ m_vecMIValueResult.clear();
+ for( MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++ )
+ {
+ CMICmnMIValueTuple miValueTuple;
+ if( !rSessionInfo.MIResponseFormFrameInfo( thread, nLevel, miValueTuple ) )
+ return MIstatus::failure;
+
+ const CMICmnMIValueResult miValueResult8( "frame", miValueTuple );
+ m_vecMIValueResult.push_back( miValueResult8 );
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListFrames::Acknowledge( void )
+{
+ if( m_nThreadFrames == 0 )
+ {
+ // MI print "3^done,stack=[{}]"
+ const CMICmnMIValueTuple miValueTuple;
+ const CMICmnMIValueList miValueList( miValueTuple );
+ const CMICmnMIValueResult miValueResult( "stack", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ // Build up a list of thread information from tuples
+ VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin();
+ if( it == m_vecMIValueResult.end() )
+ {
+ // MI print "3^done,stack=[{}]"
+ const CMICmnMIValueTuple miValueTuple;
+ const CMICmnMIValueList miValueList( miValueTuple );
+ const CMICmnMIValueResult miValueResult( "stack", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ CMICmnMIValueList miValueList( *it );
+ ++it;
+ while( it != m_vecMIValueResult.end() )
+ {
+ const CMICmnMIValueResult & rTuple( *it );
+ miValueList.Add( rTuple );
+
+ // Next
+ ++it;
+ }
+ const CMICmnMIValueResult miValueResult( "stack", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdStackListFrames::CreateSelf( void )
+{
+ return new CMICmdCmdStackListFrames();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListArguments constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListArguments::CMICmdCmdStackListArguments( void )
+: m_bThreadInvalid( false )
+, m_miValueList( true )
+, m_constStrArgThread( "thread" )
+, m_constStrArgPrintValues( "print-values" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-arguments";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListArguments destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListArguments::~CMICmdCmdStackListArguments( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListArguments::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListArguments::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgPrintValues, Number, m_constStrArgPrintValues );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( pArgThread->GetFound() )
+ {
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
+ m_bThreadInvalid = !thread.IsValid();
+ if( m_bThreadInvalid )
+ return MIstatus::success;
+
+ const lldb::StopReason eStopReason = thread.GetStopReason();
+ if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) )
+ {
+ m_bThreadInvalid = true;
+ return MIstatus::success;
+ }
+
+
+ const MIuint nFrames = thread.GetNumFrames();
+ for( MIuint i = 0; i < nFrames; i++ )
+ {
+ lldb::SBFrame frame = thread.GetFrameAtIndex( i );
+ CMICmnMIValueList miValueList( true );
+ const MIuint maskVarTypes = 0x1000;
+ if( !rSessionInfo.MIResponseFormVariableInfo3( frame, maskVarTypes, miValueList ) )
+ return MIstatus::failure;
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", i ) );
+ const CMICmnMIValueResult miValueResult( "level", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueResult miValueResult2( "args", miValueList );
+ miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueResult miValueResult3( "frame", miValueTuple );
+ m_miValueList.Add( miValueResult3 );
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListArguments::Acknowledge( void )
+{
+ if( m_bThreadInvalid )
+ {
+ // MI print "%s^done,stack-args=[]"
+ const CMICmnMIValueList miValueList( true );
+ const CMICmnMIValueResult miValueResult( "stack-args", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print "%s^done,stack-args=[frame={level=\"0\",args=[%s]},frame={level=\"1\",args=[%s]}]"
+ const CMICmnMIValueResult miValueResult4( "stack-args", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdStackListArguments::CreateSelf( void )
+{
+ return new CMICmdCmdStackListArguments();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListLocals constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListLocals::CMICmdCmdStackListLocals( void )
+: m_bThreadInvalid( false )
+, m_miValueList( true )
+, m_constStrArgThread( "thread" )
+, m_constStrArgFrame( "frame" )
+, m_constStrArgPrintValues( "print-values" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-locals";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListLocals destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListLocals::~CMICmdCmdStackListLocals( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListLocals::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListLocals::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgFrame, OptionLong, m_constStrArgFrame );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( pArgThread->GetFound() )
+ {
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+ MIuint64 nFrame = UINT64_MAX;
+ if( pArgFrame->GetFound() )
+ {
+ if( !pArgFrame->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nFrame ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
+ m_bThreadInvalid = !thread.IsValid();
+ if( m_bThreadInvalid )
+ return MIstatus::success;
+
+ const lldb::StopReason eStopReason = thread.GetStopReason();
+ if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) )
+ {
+ m_bThreadInvalid = true;
+ return MIstatus::success;
+ }
+
+ const MIuint nFrames = thread.GetNumFrames(); MIunused( nFrames );
+ lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex( nFrame ) : thread.GetSelectedFrame();
+ CMICmnMIValueList miValueList( true );
+ const MIuint maskVarTypes = 0x0110;
+ if( !rSessionInfo.MIResponseFormVariableInfo( frame, maskVarTypes, miValueList ) )
+ return MIstatus::failure;
+
+ m_miValueList = miValueList;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListLocals::Acknowledge( void )
+{
+ if( m_bThreadInvalid )
+ {
+ // MI print "%s^done,locals=[]"
+ const CMICmnMIValueList miValueList( true );
+ const CMICmnMIValueResult miValueResult( "locals", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print "%s^done,locals=[%s]"
+ const CMICmnMIValueResult miValueResult( "locals", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdStackListLocals::CreateSelf( void )
+{
+ return new CMICmdCmdStackListLocals();
+}
+
diff --git a/tools/lldb-mi/MICmdCmdStack.h b/tools/lldb-mi/MICmdCmdStack.h
new file mode 100644
index 000000000000..0c3a291d5870
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdStack.h
@@ -0,0 +1,184 @@
+//===-- MICmdCmdStack.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdStack.h
+//
+// Overview: CMICmdCmdStackInfoDepth interface.
+// CMICmdCmdStackListFrames interface.
+// CMICmdCmdStackListArguments interface.
+// CMICmdCmdStackListLocals interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-info-depth".
+// Gotchas: None.
+// Authors: Illya Rudkin 21/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdStackInfoDepth : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdStackInfoDepth( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackInfoDepth( void );
+
+// Attributes:
+private:
+ MIuint m_nThreadFrames;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgMaxDepth; // Not handled by *this command
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-list-frames".
+// Gotchas: None.
+// Authors: Illya Rudkin 21/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdStackListFrames : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdStackListFrames( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackListFrames( void );
+
+// Typedefs:
+private:
+ typedef std::vector< CMICmnMIValueResult > VecMIValueResult_t;
+
+// Attributes:
+private:
+ MIuint m_nThreadFrames;
+ VecMIValueResult_t m_vecMIValueResult;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgFrameLow;
+ const CMIUtilString m_constStrArgFrameHigh;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-list-arguments".
+// Gotchas: None.
+// Authors: Illya Rudkin 24/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdStackListArguments : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdStackListArguments( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackListArguments( void );
+
+// Attributes:
+private:
+ bool m_bThreadInvalid; // True = yes invalid thread, false = thread object valid
+ CMICmnMIValueList m_miValueList;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-list-locals".
+// Gotchas: None.
+// Authors: Illya Rudkin 24/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdStackListLocals : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdStackListLocals( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackListLocals( void );
+
+// Attributes:
+private:
+ bool m_bThreadInvalid; // True = yes invalid thread, false = thread object valid
+ CMICmnMIValueList m_miValueList;
+ const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
+ const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+};
+
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.cpp b/tools/lldb-mi/MICmdCmdSupportInfo.cpp
new file mode 100644
index 000000000000..e6f96f094e58
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSupportInfo.cpp
@@ -0,0 +1,129 @@
+//===-- MICmdCmdSupportListInfo.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdSupportListInfo.cpp
+//
+// Overview: CMICmdCmdSupportInfoMiCmdQuery implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdSupportInfo.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmdArgValString.h"
+#include "MICmdFactory.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSupportInfoMiCmdQuery constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSupportInfoMiCmdQuery::CMICmdCmdSupportInfoMiCmdQuery( void )
+: m_bCmdFound( false )
+, m_constStrArgCmdName( "cmd_name" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "info-gdb-mi-command";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdSupportInfoMiCmdQuery::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSupportInfoMiCmdQuery destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSupportInfoMiCmdQuery::~CMICmdCmdSupportInfoMiCmdQuery( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSupportInfoMiCmdQuery::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgCmdName, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSupportInfoMiCmdQuery::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgNamedCmdName, String, m_constStrArgCmdName );
+ const CMIUtilString & rCmdToQuery( pArgNamedCmdName->GetValue() );
+ const MIuint nLen = rCmdToQuery.length();
+ const CMICmdFactory & rCmdFactory = CMICmdFactory::Instance();
+ if( (nLen > 1) && (rCmdToQuery[ 0 ] == '-') )
+ m_bCmdFound = rCmdFactory.CmdExist( rCmdToQuery.substr( 1, nLen - 1 ).c_str() );
+ else
+ m_bCmdFound = rCmdFactory.CmdExist( rCmdToQuery );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSupportInfoMiCmdQuery::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( m_bCmdFound ? "true" : "false" );
+ const CMICmnMIValueResult miValueResult( "exists", miValueConst );
+ const CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueResult miValueResult2( "command", miValueTuple );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult2 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdSupportInfoMiCmdQuery::CreateSelf( void )
+{
+ return new CMICmdCmdSupportInfoMiCmdQuery();
+}
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.h b/tools/lldb-mi/MICmdCmdSupportInfo.h
new file mode 100644
index 000000000000..2633e99ce10e
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSupportInfo.h
@@ -0,0 +1,69 @@
+//===-- MICmdCmdSupportInfo.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdSupportInfo.h
+//
+// Overview: CMICmdCmdSupportInfoMiCmdQuery interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "info-gdb-mi-command".
+// This command does not follow the MI documentation exactly.
+// Gotchas: None.
+// Authors: Illya Rudkin 06/05/2014.
+// Changes: None.
+//--
+class CMICmdCmdSupportInfoMiCmdQuery : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdSupportInfoMiCmdQuery( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdSupportInfoMiCmdQuery( void );
+
+// Attributes:
+private:
+ bool m_bCmdFound; // True = query for the command in command factory found, false = not found not recognised
+ const CMIUtilString m_constStrArgCmdName;
+};
+
diff --git a/tools/lldb-mi/MICmdCmdSupportList.cpp b/tools/lldb-mi/MICmdCmdSupportList.cpp
new file mode 100644
index 000000000000..2e4beb3edc85
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSupportList.cpp
@@ -0,0 +1,102 @@
+//===-- MICmdCmdSupportList.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdSupportList.cpp
+//
+// Overview: CMICmdCmdSupportListFeatures implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdSupportList.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIValueList.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSupportListFeatures constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSupportListFeatures::CMICmdCmdSupportListFeatures( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "list-features";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdSupportListFeatures::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSupportListFeatures destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSupportListFeatures::~CMICmdCmdSupportListFeatures( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSupportListFeatures::Execute( void )
+{
+ // Do nothing
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdSupportListFeatures::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( "data-read-memory-bytes" );
+ const CMICmnMIValueList miValueList( miValueConst );
+ const CMICmnMIValueResult miValueResult( "features", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdSupportListFeatures::CreateSelf( void )
+{
+ return new CMICmdCmdSupportListFeatures();
+}
diff --git a/tools/lldb-mi/MICmdCmdSupportList.h b/tools/lldb-mi/MICmdCmdSupportList.h
new file mode 100644
index 000000000000..d9909a88997f
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSupportList.h
@@ -0,0 +1,63 @@
+//===-- MICmdCmdSupportList.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdSupportList.h
+//
+// Overview: CMICmdCmdSupportListFeatures interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "list-features".
+// This command does not follow the MI documentation exactly.
+// Gotchas: None.
+// Authors: Illya Rudkin 03/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdSupportListFeatures : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdSupportListFeatures( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdSupportListFeatures( void );
+};
+
diff --git a/tools/lldb-mi/MICmdCmdTarget.cpp b/tools/lldb-mi/MICmdCmdTarget.cpp
new file mode 100644
index 000000000000..60c1c5e4bba2
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdTarget.cpp
@@ -0,0 +1,217 @@
+//===-- MICmdCmdTarget.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdTarget.cpp
+//
+// Overview: CMICmdCmdTargetSelect implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBStream.h>
+#include <lldb/API/SBCommandInterpreter.h>
+#include <lldb/API/SBCommandReturnObject.h>
+
+// In-house headers:
+#include "MICmdCmdTarget.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIOutOfBandRecord.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValString.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdTargetSelect constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdTargetSelect::CMICmdCmdTargetSelect( void )
+: m_constStrArgNamedType( "type" )
+, m_constStrArgNamedParameters( "parameters" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "target-select";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdTargetSelect::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdTargetSelect destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdTargetSelect::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedType, true, true )) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedParameters, true, true )) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Synopsis: -target-select type parameters ...
+// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdTargetSelect::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgType, String, m_constStrArgNamedType );
+ CMICMDBASE_GETOPTION( pArgParameters, String, m_constStrArgNamedParameters );
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+
+ // Check we have a valid target
+ // Note: target created via 'file-exec-and-symbols' command
+ if( !rSessionInfo.m_lldbTarget.IsValid() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET_CURRENT ), m_cmdData.strMiCmd.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ // Verify that we are executing remotely
+ const CMIUtilString & rRemoteType( pArgType->GetValue() );
+ if( rRemoteType != "remote" )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET_TYPE ), m_cmdData.strMiCmd.c_str(), rRemoteType.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ // Create a URL pointing to the remote gdb stub
+ const CMIUtilString strUrl = CMIUtilString::Format( "connect://%s", pArgParameters->GetValue().c_str() );
+
+ // Ask LLDB to collect to the target port
+ const MIchar * pPlugin( "gdb-remote" );
+ lldb::SBError error;
+ lldb::SBProcess process = rSessionInfo.m_lldbTarget.ConnectRemote( rSessionInfo.m_rLlldbListener, strUrl.c_str(), pPlugin, error );
+
+ // Verify that we have managed to connect successfully
+ lldb::SBStream errMsg;
+ if( !process.IsValid() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET_PLUGIN ), m_cmdData.strMiCmd.c_str(), errMsg.GetData() ) );
+ return MIstatus::failure;
+ }
+ if( error.Fail() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_CONNECT_TO_TARGET ), m_cmdData.strMiCmd.c_str(), errMsg.GetData() ) );
+ return MIstatus::failure;
+ }
+
+ // Save the process in the session info
+ // Note: Order is important here since this process handle may be used by CMICmnLLDBDebugHandleEvents
+ // which can fire when interpreting via HandleCommand() below.
+ rSessionInfo.m_lldbProcess = process;
+
+ // Set the environment path if we were given one
+ CMIUtilString strWkDir;
+ if( rSessionInfo.SharedDataRetrieve< CMIUtilString >( rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir ) )
+ {
+ lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
+ if( !rDbgr.SetCurrentPlatformSDKRoot( strWkDir.c_str() ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "target-select" ) );
+ return MIstatus::failure;
+ }
+ }
+
+ // Set the shared object path if we were given one
+ CMIUtilString strSolibPath;
+ if( rSessionInfo.SharedDataRetrieve< CMIUtilString >( rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath ) )
+ {
+ lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
+ lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter();
+
+ CMIUtilString strCmdString = CMIUtilString::Format( "target modules search-paths add . %s", strSolibPath.c_str() );
+
+ lldb::SBCommandReturnObject retObj;
+ cmdIterpreter.HandleCommand( strCmdString.c_str(), retObj, false );
+
+ if( !retObj.Succeeded() )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "target-select" ) );
+ return MIstatus::failure;
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdTargetSelect::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Connected );
+ m_miResultRecord = miRecordResult;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ // Prod the client i.e. Eclipse with out-of-band results to help it 'continue' because it is using LLDB debugger
+ // Give the client '=thread-group-started,id="i1"'
+ m_bHasResultRecordExtra = true;
+ const CMICmnMIValueConst miValueConst2( "i1" );
+ const CMICmnMIValueResult miValueResult2( "id", miValueConst2 );
+ const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
+ const CMICmnMIValueConst miValueConst( strPid );
+ const CMICmnMIValueResult miValueResult( "pid", miValueConst );
+ CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2 );
+ miOutOfBand.Add( miValueResult );
+ m_miResultRecordExtra = miOutOfBand.GetString();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdTargetSelect::CreateSelf( void )
+{
+ return new CMICmdCmdTargetSelect();
+}
diff --git a/tools/lldb-mi/MICmdCmdTarget.h b/tools/lldb-mi/MICmdCmdTarget.h
new file mode 100644
index 000000000000..f904f20ee4f6
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdTarget.h
@@ -0,0 +1,70 @@
+//===-- MICmdCmdTarget.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdTarget.h
+//
+// Overview: CMICmdCmdTargetSelect interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "target-select".
+// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
+// Gotchas: None.
+// Authors: Illya Rudkin 05/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdTargetSelect : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdTargetSelect( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdTargetSelect( void );
+
+// Attributes:
+private:
+ const CMIUtilString m_constStrArgNamedType;
+ const CMIUtilString m_constStrArgNamedParameters;
+};
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp
new file mode 100644
index 000000000000..8cfaae804931
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdThread.cpp
@@ -0,0 +1,207 @@
+//===-- MICmdCmdThread.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdThread.cpp
+//
+// Overview: CMICmdCmdThreadInfo implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBBreakpointLocation.h>
+#include <lldb/API/SBThread.h>
+
+// In-house headers:
+#include "MICmdCmdThread.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValNumber.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdThreadInfo constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdThreadInfo::CMICmdCmdThreadInfo( void )
+: m_bSingleThread( false )
+, m_bThreadInvalid( true )
+, m_constStrArgNamedThreadId( "thread-id" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "thread-info";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdThreadInfo::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdThreadInfo destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdThreadInfo::~CMICmdCmdThreadInfo( void )
+{
+ m_vecMIValueTuple.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdThreadInfo::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedThreadId, false, true )) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdThreadInfo::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThreadId, Number, m_constStrArgNamedThreadId );
+ MIuint nThreadId = 0;
+ if( pArgThreadId->GetFound() && pArgThreadId->GetValid() )
+ {
+ m_bSingleThread = true;
+ nThreadId = static_cast< MIuint >( pArgThreadId->GetValue() );
+ }
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = rProcess.GetSelectedThread();
+
+ if( m_bSingleThread )
+ {
+ thread = rProcess.GetThreadByIndexID( nThreadId );
+ m_bThreadInvalid = thread.IsValid();
+ if( !m_bThreadInvalid )
+ return MIstatus::success;
+
+ CMICmnMIValueTuple miTuple;
+ if( !rSessionInfo.MIResponseFormThreadInfo3( m_cmdData, thread, miTuple ) )
+ return MIstatus::failure;
+
+ m_miValueTupleThread = miTuple;
+
+ return MIstatus::success;
+ }
+
+ // Multiple threads
+ m_vecMIValueTuple.clear();
+ const MIuint nThreads = rProcess.GetNumThreads();
+ for( MIuint i = 0; i < nThreads; i++ )
+ {
+ lldb::SBThread thread = rProcess.GetThreadAtIndex( i );
+ if( thread.IsValid() )
+ {
+ CMICmnMIValueTuple miTuple;
+ if( !rSessionInfo.MIResponseFormThreadInfo3( m_cmdData, thread, miTuple ) )
+ return MIstatus::failure;
+
+ m_vecMIValueTuple.push_back( miTuple );
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdThreadInfo::Acknowledge( void )
+{
+ if( m_bSingleThread )
+ {
+ if( !m_bThreadInvalid )
+ {
+ const CMICmnMIValueConst miValueConst( "invalid thread id" );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
+ const CMICmnMIValueList miValueList( m_miValueTupleThread );
+ const CMICmnMIValueResult miValueResult( "threads", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // Build up a list of thread information from tuples
+ VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
+ if( it == m_vecMIValueTuple.end() )
+ {
+ const CMICmnMIValueConst miValueConst( "[]" );
+ const CMICmnMIValueResult miValueResult( "threads", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ CMICmnMIValueList miValueList( *it );
+ ++it;
+ while( it != m_vecMIValueTuple.end() )
+ {
+ const CMICmnMIValueTuple & rTuple( *it );
+ miValueList.Add( rTuple );
+
+ // Next
+ ++it;
+ }
+
+ const CMICmnMIValueResult miValueResult( "threads", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdThreadInfo::CreateSelf( void )
+{
+ return new CMICmdCmdThreadInfo();
+}
diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h
new file mode 100644
index 000000000000..33cd786a8cac
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdThread.h
@@ -0,0 +1,76 @@
+//===-- MICmdCmdThread.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdThread.h
+//
+// Overview: CMICmdCmdThreadInfo interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+#include "MICmnMIValueTuple.h"
+#include "MICmnMIValueList.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "thread-info".
+// Gotchas: None.
+// Authors: Illya Rudkin 07/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdThreadInfo : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdThreadInfo( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ virtual bool ParseArgs( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdThreadInfo( void );
+
+// Typedefs:
+private:
+ typedef std::vector< CMICmnMIValueTuple > VecMIValueTuple_t;
+
+// Attributes:
+private:
+ CMICmnMIValueTuple m_miValueTupleThread;
+ bool m_bSingleThread; // True = yes single thread, false = multiple threads
+ bool m_bThreadInvalid; // True = invalid, false = ok
+ VecMIValueTuple_t m_vecMIValueTuple;
+ const CMIUtilString m_constStrArgNamedThreadId;
+};
diff --git a/tools/lldb-mi/MICmdCmdTrace.cpp b/tools/lldb-mi/MICmdCmdTrace.cpp
new file mode 100644
index 000000000000..8623db9eb151
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdTrace.cpp
@@ -0,0 +1,99 @@
+//===-- MICmdCmdTrace.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdTrace.cpp
+//
+// Overview: CMICmdCmdTraceStatus implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// In-house headers:
+#include "MICmdCmdTrace.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdTraceStatus constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdTraceStatus::CMICmdCmdTraceStatus( void )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "trace-status";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdTraceStatus::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdTraceStatus destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdTraceStatus::~CMICmdCmdTraceStatus( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdTraceStatus::Execute( void )
+{
+ // Do nothing
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdTraceStatus::Acknowledge( void )
+{
+ const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED ) );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdTraceStatus::CreateSelf( void )
+{
+ return new CMICmdCmdTraceStatus();
+}
diff --git a/tools/lldb-mi/MICmdCmdTrace.h b/tools/lldb-mi/MICmdCmdTrace.h
new file mode 100644
index 000000000000..2192d007a599
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdTrace.h
@@ -0,0 +1,61 @@
+//===-- MICmdCmdTrace.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdTrace.h
+//
+// Overview: CMICmdCmdTraceStatus interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "trace-status".
+// Gotchas: None.
+// Authors: Illya Rudkin 07/03/2014.
+// Changes: None.
+//--
+class CMICmdCmdTraceStatus : public CMICmdBase
+{
+// Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase * CreateSelf( void );
+
+// Methods:
+public:
+ /* ctor */ CMICmdCmdTraceStatus( void );
+
+// Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute( void );
+ virtual bool Acknowledge( void );
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdTraceStatus( void );
+};
diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp
new file mode 100644
index 000000000000..346d69600760
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdVar.cpp
@@ -0,0 +1,1492 @@
+//===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdVar.cpp
+//
+// Overview: CMICmdCmdVarCreate implementation.
+// CMICmdCmdVarUpdate implementation.
+// CMICmdCmdVarDelete implementation.
+// CMICmdCmdVarAssign implementation.
+// CMICmdCmdVarSetFormat implementation.
+// CMICmdCmdVarListChildren implementation.
+// CMICmdCmdVarEvaluateExpression implementation.
+// CMICmdCmdVarInfoPathExpression implementation.
+// CMICmdCmdVarShowAttributes implementation.
+//
+// Environment: Compilers: Visual C++ 12.
+// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
+// Libraries: See MIReadmetxt.
+//
+// Copyright: None.
+//--
+
+// Third Party Headers:
+#include <lldb/API/SBStream.h>
+#include <lldb/API/SBThread.h>
+
+// In-house headers:
+#include "MICmdCmdVar.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmnLLDBProxySBValue.h"
+#include "MICmnLLDBUtilSBValue.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarCreate constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarCreate::CMICmdCmdVarCreate( void )
+: m_nChildren( 0 )
+, m_nMore( 0 )
+, m_nThreadId( 0 )
+, m_strType( "??" )
+, m_bValid( false )
+, m_strValue( "??" )
+, m_constStrArgThread( "thread" )
+, m_constStrArgThreadGroup( "thread-group" )
+, m_constStrArgFrame( "frame" )
+, m_constStrArgName( "name" )
+, m_constStrArgFrameAddr( "frame-addr" )
+, m_constStrArgExpression( "expression" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-create";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarCreate destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarCreate::~CMICmdCmdVarCreate( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarCreate::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFrameAddr, false, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarCreate::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
+ CMICMDBASE_GETOPTION( pArgFrame, OptionLong, m_constStrArgFrame );
+ CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
+ CMICMDBASE_GETOPTION( pArgFrameAddr, String, m_constStrArgFrameAddr );
+ CMICMDBASE_GETOPTION( pArgExpression, String, m_constStrArgExpression );
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
+ return MIstatus::failure;
+ }
+ m_nThreadId = nThreadId;
+
+ // Retrieve the --frame option's number
+ MIuint64 nFrame = UINT64_MAX;
+ if( !pArgFrame->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nFrame ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ const CMICmdArgValOptionLong::VecArgObjPtr_t & rVecFrameId( pArgFrame->GetExpectedOptions() );
+ CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 = rVecFrameId.begin();
+ if( it2 != rVecFrameId.end() )
+ {
+ const CMICmdArgValNumber * pOption = static_cast< CMICmdArgValNumber * >( *it2 );
+ nFrame = pOption->GetValue();
+ }
+
+ bool bAutoName = false;
+ const CMIUtilString strArgName;
+ if( pArgName->GetFound() )
+ {
+ const CMIUtilString & rArg = pArgName->GetValue();
+ bAutoName = (rArg == "-");
+ }
+
+ const CMIUtilString & rStrExpression( pArgExpression->GetValue() );
+ m_strExpression = rStrExpression;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ m_strVarName = "<unnamedvariable>";
+ if( bAutoName )
+ {
+ m_strVarName = CMIUtilString::Format( "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet() );
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
+ }
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = rProcess.GetThreadByIndexID( nThreadId );
+ lldb::SBFrame frame = thread.GetFrameAtIndex( nFrame );
+ lldb::SBValue value = frame.FindVariable( rStrExpression.c_str() );
+ if( !value.IsValid() )
+ value = frame.EvaluateExpression( rStrExpression.c_str() );
+ if( value.IsValid() )
+ {
+ m_bValid = true;
+ m_nChildren = value.GetNumChildren();
+ m_strType = CMICmnLLDBUtilSBValue( value ).GetTypeNameDisplay();
+
+ // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
+ CMICmnLLDBDebugSessionInfoVarObj varObj( rStrExpression, m_strVarName, value );
+ m_strValue = varObj.GetValueFormatted();
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarCreate::Acknowledge( void )
+{
+ if( m_bValid )
+ {
+ // MI print "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
+ const CMICmnMIValueConst miValueConst( m_strVarName );
+ CMICmnMIValueResult miValueResultAll( "name", miValueConst );
+ const CMIUtilString strNumChild( CMIUtilString::Format( "%d", m_nChildren ) );
+ const CMICmnMIValueConst miValueConst2( strNumChild );
+ miValueResultAll.Add( "numchild", miValueConst2 );
+ const CMICmnMIValueConst miValueConst3( m_strValue );
+ miValueResultAll.Add( "value", miValueConst3 );
+ const CMICmnMIValueConst miValueConst4( m_strType );
+ miValueResultAll.Add( "type", miValueConst4 );
+ const CMIUtilString strThreadId( CMIUtilString::Format( "%llu", m_nThreadId ) );
+ const CMICmnMIValueConst miValueConst5( strThreadId );
+ miValueResultAll.Add( "thread-id", miValueConst5 );
+ const CMICmnMIValueConst miValueConst6( "0" );
+ miValueResultAll.Add( "has_more", miValueConst6 );
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultAll );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_CREATION_FAILED ), m_strExpression.c_str() ) );
+ CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdVarCreate::CreateSelf( void )
+{
+ return new CMICmdCmdVarCreate();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarUpdate constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarUpdate::CMICmdCmdVarUpdate( void )
+: m_constStrArgPrintValues( "print-values" )
+, m_constStrArgName( "name" )
+, m_bValueChangedArrayType( false )
+, m_bValueChangedCompositeType( false )
+, m_bValueChangedNormalType( false )
+, m_miValueList( true )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-update";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarUpdate destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarUpdate::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, false, false ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarUpdate::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
+
+ const CMIUtilString & rVarObjName( pArgName->GetValue() );
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ if( !CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( rVarObjName, varObj ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str() ) );
+ return MIstatus::failure;
+ }
+
+ const CMIUtilString & rVarRealName( varObj.GetNameReal() ); MIunused( rVarRealName );
+ lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
+ const bool bValid = rValue.IsValid();
+ if( bValid && rValue.GetValueDidChange() )
+ {
+ m_bValueChangedNormalType = true;
+ varObj.UpdateValue();
+ m_strValueName = rVarObjName;
+ return MIstatus::success;
+ }
+
+ // Examine an array type variable
+ if( !ExamineSBValueForChange( varObj, false, m_bValueChangedArrayType ) )
+ return MIstatus::failure;
+
+ // Handle composite types i.e. struct or arrays
+ const MIuint nChildren = rValue.GetNumChildren();
+ for( MIuint i = 0; i < nChildren; i++ )
+ {
+ lldb::SBValue member = rValue.GetChildAtIndex( i );
+ if( !member.IsValid() )
+ continue;
+
+ const CMIUtilString varName( CMIUtilString::Format( "%s.%s", rVarObjName.c_str(), member.GetName() ) );
+ if( member.GetValueDidChange() )
+ {
+ // Handle composite
+ const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) );
+ const CMIUtilString strInScope( member.IsInScope() ? "true" : "false" );
+ MIFormResponse( varName, strValue, strInScope );
+
+ m_bValueChangedCompositeType = true;
+ }
+ else
+ {
+ // Handle array of composites
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) )
+ {
+ bool bValueChanged = false;
+ if( ExamineSBValueForChange( varObj, true, bValueChanged ) )
+ {
+ if( bValueChanged && CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) )
+ {
+ lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
+ const bool bValid = rValue.IsValid();
+ const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" );
+ const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" );
+ MIFormResponse( varName, strValue, strInScope );
+
+ m_bValueChangedCompositeType = true;
+ }
+ }
+ else
+ return MIstatus::failure;
+ }
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarUpdate::Acknowledge( void )
+{
+ if( m_bValueChangedArrayType || m_bValueChangedNormalType )
+ {
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strValueName, varObj );
+ lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
+ const bool bValid = rValue.IsValid();
+ const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" );
+ const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" );
+
+ // MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
+ const CMICmnMIValueConst miValueConst( m_strValueName );
+ CMICmnMIValueResult miValueResult( "name", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( strValue );
+ CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
+ miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueConst miValueConst3( strInScope );
+ CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
+ miValueTuple.Add( miValueResult3 );
+ const CMICmnMIValueConst miValueConst4( "false" );
+ CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
+ miValueTuple.Add( miValueResult4 );
+ const CMICmnMIValueConst miValueConst5( "0" );
+ CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 );
+ miValueTuple.Add( miValueResult5 );
+ const CMICmnMIValueList miValueList( miValueTuple );
+ CMICmnMIValueResult miValueResult6( "changelist", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+ else if( m_bValueChangedCompositeType )
+ {
+ // MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"},{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
+ CMICmnMIValueResult miValueResult6( "changelist", m_miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ // MI: "%s^done,changelist=[]"
+ const CMICmnMIValueList miValueList( true );
+ CMICmnMIValueResult miValueResult6( "changelist", miValueList );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdVarUpdate::CreateSelf( void )
+{
+ return new CMICmdCmdVarUpdate();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Form the MI response for multiple variables.
+// Type: Method.
+// Args: vrStrVarName - (R) Session var object's name.
+// vrStrValue - (R) Text version of the value held in the variable.
+// vrStrScope - (R) In scope "yes" or "no".
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarUpdate::MIFormResponse( const CMIUtilString & vrStrVarName, const CMIUtilString & vrStrValue, const CMIUtilString & vrStrScope )
+{
+ // MI print "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
+ const CMICmnMIValueConst miValueConst( vrStrVarName );
+ CMICmnMIValueResult miValueResult( "name", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( vrStrValue );
+ CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
+ bool bOk = miValueTuple.Add( miValueResult2 );
+ const CMICmnMIValueConst miValueConst3( vrStrScope );
+ CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
+ bOk = bOk && miValueTuple.Add( miValueResult3 );
+ const CMICmnMIValueConst miValueConst4( "false" );
+ CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
+ bOk = bOk && miValueTuple.Add( miValueResult4 );
+ const CMICmnMIValueConst miValueConst5( "0" );
+ CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 );
+ bOk = bOk && miValueTuple.Add( miValueResult5 );
+ bOk = bOk && m_miValueList.Add( miValueTuple );
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Determine if the var object is a array type variable. LLDB does not 'detect'
+// a value change for some types like elements in an array so have to re-evaluate
+// the expression again.
+// Type: Method.
+// Args: vrVarObj - (R) Session var object to examine.
+// vrwbChanged - (W) True = Is an array type and it changed,
+// False = Not an array type or not changed.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarUpdate::ExamineSBValueForChange( const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj, const bool vbIgnoreVarType, bool & vrwbChanged )
+{
+ vrwbChanged = false;
+
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBThread thread = rProcess.GetSelectedThread();
+ if( thread.GetNumFrames() == 0 )
+ {
+ return MIstatus::success;
+ }
+
+ const CMIUtilString & strVarObjParentName = vrVarObj.GetVarParentName();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ const CMIUtilString & rExpression( vrVarObj.GetNameReal() );
+ CMIUtilString varExpression;
+ if( strVarObjParentName.empty() )
+ {
+ varExpression = rExpression;
+ }
+ else
+ {
+ CMICmnLLDBDebugSessionInfoVarObj varObjParent;
+ if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( strVarObjParentName, varObjParent ) )
+ varExpression = CMIUtilString::Format( "%s.%s", varObjParent.GetNameReal().c_str(), rExpression.c_str() );
+ else
+ {
+ // The parent is only assigned in the CMICmdCmdVarListChildren command, we have a problem, need to investigate
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), strVarObjParentName.c_str() ) );
+ return MIstatus::failure;
+ }
+ }
+
+ lldb::SBValue value = frame.EvaluateExpression( varExpression.c_str() );
+ if( !value.IsValid() )
+ value = frame.FindVariable( rExpression.c_str() );
+ if( value.IsValid() )
+ {
+ lldb::SBType valueType = value.GetType();
+ const lldb::BasicType eValueType = valueType.GetBasicType();
+ if( vbIgnoreVarType || (eValueType != lldb::BasicType::eBasicTypeInvalid) )
+ {
+ MIuint64 nPrevValue = 0;
+ MIuint64 nRevaluateValue = 0;
+ lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrVarObj.GetValue() );
+ if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( rValue, nPrevValue ) &&
+ CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nRevaluateValue ) &&
+ (nPrevValue != nRevaluateValue) )
+ {
+ // Have a value change so update the var object
+ vrwbChanged = true;
+ const CMICmnLLDBDebugSessionInfoVarObj varObj( rExpression, vrVarObj.GetName(), value, strVarObjParentName );
+ }
+ }
+ }
+
+ return MIstatus::success;
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarDelete constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarDelete::CMICmdCmdVarDelete( void )
+: m_constStrArgName( "name" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-delete";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarDelete::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarDelete destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarDelete::~CMICmdCmdVarDelete( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarDelete::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
+
+ const CMIUtilString & rVarObjName( pArgName->GetValue() );
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete( rVarObjName );
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarDelete::Acknowledge( void )
+{
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdVarDelete::CreateSelf( void )
+{
+ return new CMICmdCmdVarDelete();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarAssign constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarAssign::CMICmdCmdVarAssign( void )
+: m_bOk( true )
+, m_constStrArgName( "name" )
+, m_constStrArgExpression( "expression" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-assign";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarAssign destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarAssign::~CMICmdCmdVarAssign( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarAssign::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarAssign::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
+ CMICMDBASE_GETOPTION( pArgExpression, String, m_constStrArgExpression );
+
+ const CMIUtilString & rVarObjName( pArgName->GetValue() );
+ const CMIUtilString & rExpression( pArgExpression->GetValue() );
+
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ if( !CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( rVarObjName, varObj ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str() ) );
+ return MIstatus::failure;
+ }
+ m_varObjName = rVarObjName;
+
+ CMIUtilString strExpression( rExpression.Trim() );
+ strExpression = strExpression.Trim( '"' );
+ lldb::SBValue & rValue( const_cast< lldb::SBValue & >( varObj.GetValue() ) );
+ m_bOk = rValue.SetValueFromCString( strExpression.c_str() );
+ if( m_bOk )
+ varObj.UpdateValue();
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarAssign::Acknowledge( void )
+{
+ if( m_bOk )
+ {
+ // MI print "%s^done,value=\"%s\""
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_varObjName, varObj );
+ const CMICmnMIValueConst miValueConst( varObj.GetValueFormatted() );
+ const CMICmnMIValueResult miValueResult( "value", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ const CMICmnMIValueConst miValueConst( "expression could not be evaluated" );
+ const CMICmnMIValueResult miValueResult( "msg", miValueConst );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdVarAssign::CreateSelf( void )
+{
+ return new CMICmdCmdVarAssign();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarSetFormat constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat( void )
+: m_constStrArgName( "name" )
+, m_constStrArgFormatSpec( "format-spec" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-set-format";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarSetFormat destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat( void )
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarSetFormat::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFormatSpec, true, true ) ) );
+ return (bOk && ParseValidateCmdOptions() );
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command does work in this function.
+// The command is likely to communicate with the LLDB SBDebugger in here.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarSetFormat::Execute( void )
+{
+ CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
+ CMICMDBASE_GETOPTION( pArgFormatSpec, String, m_constStrArgFormatSpec );
+
+ const CMIUtilString & rVarObjName( pArgName->GetValue() );
+ const CMIUtilString & rExpression( pArgFormatSpec->GetValue() );
+
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ if( !CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( rVarObjName, varObj ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str() ) );
+ return MIstatus::failure;
+ }
+ if( !varObj.SetVarFormat( CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString( rExpression ) ) )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_ENUM_INVALID ), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str(), rExpression.c_str() ) );
+ return MIstatus::failure;
+ }
+ varObj.UpdateValue();
+
+ m_varObjName = rVarObjName;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command prepares a MI Record Result
+// for the work carried out in the Execute().
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarSetFormat::Acknowledge( void )
+{
+ // MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
+ CMICmnLLDBDebugSessionInfoVarObj varObj;
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_varObjName, varObj );
+ const CMICmnMIValueConst miValueConst( m_varObjName );
+ const CMICmnMIValueResult miValueResult( "name", miValueConst );
+ CMICmnMIValueTuple miValueTuple( miValueResult );
+ const CMICmnMIValueConst miValueConst2( varObj.GetValueFormatted() );
+ const CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
+ miValueTuple.Add( miValueResult2 );
+ lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
+ const CMICmnMIValueConst miValueConst3( rValue.IsInScope() ? "true" : "false" );
+ const CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
+ miValueTuple.Add( miValueResult3 );
+ const CMICmnMIValueConst miValueConst4( "false" );
+ const CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
+ miValueTuple.Add( miValueResult4 );
+ const CMICmnMIValueConst miValueConst5( "0" );
+ const CMICmnMIValueResult miValueResult5( "type_changed", miValueConst5 );
+ miValueTuple.Add( miValueResult5 );
+ const CMICmnMIValueList miValueList( miValueTuple );
+ const CMICmnMIValueResult miValueResult6( "changelist", miValueList );
+
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Static method.
+// Args: None.
+// Return: CMICmdBase * - Pointer to a new command.
+// Throws: None.
+//--
+CMICmdBase * CMICmdCmdVarSetFormat::CreateSelf( void )
+{
+ return new CMICmdCmdVarSetFormat();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarListChildren constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarListChildren::CMICmdCmdVarListChildren( void )
+: m_bValueValid( false )
+, m_nChildren( 0 )
+, m_constStrArgPrintValues( "print-values" )
+, m_constStrArgName( "name" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "var-list-children";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdVarListChildren destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren( void )
+{
+ m_vecMiValueResult.clear();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The parses the command line options
+// arguments to extract values for each of those arguments.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdVarListChildren::ParseArgs( void )
+{
+ bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, false, false ) ) );
+ bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, t