[Lldb-commits] [PATCH] lldb-mi support for CLI commands and -s option
dawn at burble.org
dawn at burble.org
Tue Nov 18 23:27:30 PST 2014
Doh! Let's try this again...
On Tue, Nov 18, 2014 at 11:13:32AM -0800, jingham at apple.com wrote:
> I didn't see a patch attached to this.
>
> Jim
>
> > On Nov 18, 2014, at 8:32 AM, dawn at burble.org wrote:
> >
> > Adds support for using command files in lldb-mi via option -s, and
> > allows for non-MI commands to be entered in interpreter mode by
> > embedding them inside "-interpreter-exec" commands.
> >
> > Please review and commit?
> >
> > Thanks,
> > -Dawn
> > _______________________________________________
> > lldb-commits mailing list
> > lldb-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
-------------- next part --------------
Index: tools/lldb-mi/MIDriver.cpp
===================================================================
--- tools/lldb-mi/MIDriver.cpp (revision 222209)
+++ tools/lldb-mi/MIDriver.cpp (working copy)
@@ -22,6 +22,7 @@
// Third party headers:
#include <stdarg.h> // va_list, va_start, var_end
#include <iostream>
+#include <fstream>
#include <lldb/API/SBError.h>
// In-house headers:
@@ -68,6 +69,7 @@
, m_eCurrentDriverState(eDriverState_NotRunning)
, m_bHaveExecutableFileNamePathOnCmdLine(false)
, m_bDriverDebuggingArgExecutable(false)
+ , m_bHaveCommandFileNamePathOnCmdLine(false)
{
}
@@ -410,16 +412,17 @@
//++ ------------------------------------------------------------------------------------
// Details: Check the arguments that were passed to this program to make sure they are
-// valid and to get their argument values (if any). The following are options
-// that are only handled by *this driver:
+// valid and to get their argument values (if any). The following are the only
+// options handled by this driver:
// --executable
+// --source
// The application's options --interpreter and --executable in code act very similar.
// The --executable is necessary to differentiate whither the MI Driver is being
-// using by a client i.e. Eclipse or from the command line. Eclipse issues the option
+// using by a client (e.g. Eclipse) or from the command line. Eclipse issues the option
// --interpreter and also passes additional arguments which can be interpreted as an
-// executable if called from the command line. Using --executable tells the MI
-// Driver is being called the command line and that the executable argument is indeed
-// a specified executable an so actions commands to set up the executable for a
+// executable if called from the command line. Using --executable tells the MI Driver
+// it is being called from the command line and that the executable argument is indeed
+// a specified executable and should so actions commands to set up the executable for a
// debug session. Using --interpreter on the commnd line does not action additional
// commands to initialise a debug session and so be able to launch the process.
// Type: Overridden.
@@ -451,20 +454,40 @@
if (bHaveArgs)
{
- // Search right to left to look for the executable
+ // Search right to left to look for filenames
for (MIint i = argc - 1; i > 0; i--)
{
const CMIUtilString strArg(argv[i]);
const CMICmdArgValFile argFile;
+
+ // Check for a filename
if (argFile.IsFilePath(strArg) || CMICmdArgValString(true, false, true).IsStringArg(strArg))
{
+ // Is this the command file for the '-s' option?
+ const CMIUtilString strPrevArg(argv[i - 1]);
+ if (strPrevArg.compare("-s") == 0 || strPrevArg.compare("--source") == 0)
+ {
+ m_strCmdLineArgCommandFileNamePath = argFile.GetFileNamePath(strArg);
+ m_bHaveCommandFileNamePathOnCmdLine = true;
+ i--; // skip '-s' on the next loop
+ continue;
+ }
+ // Else, must be the executable
bHaveExecutableFileNamePath = true;
m_strCmdLineArgExecuteableFileNamePath = argFile.GetFileNamePath(strArg);
m_bHaveExecutableFileNamePathOnCmdLine = true;
}
- // This argument is also check for in CMIDriverMgr::ParseArgs()
- if (0 == strArg.compare("--executable")) // Used to specify that there is executable argument also on the command line
- { // See fn description.
+ // Report error if no command file was specified for the '-s' option
+ else if (strArg.compare("-s") == 0 || strArg.compare("--source") == 0)
+ {
+ vwbExiting = true;
+ const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF), "-s");
+ errStatus.SetErrorString(errMsg.c_str());
+ break;
+ }
+ // This argument is also checked for in CMIDriverMgr::ParseArgs()
+ else if (strArg.compare("--executable") == 0) // Used to specify that there is executable argument also on the command line
+ { // See fn description.
bHaveExecutableLongOption = true;
}
}
@@ -623,6 +646,35 @@
}
#endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
+ // Handle '-s <file>' option
+ bool bOk = MIstatus::success;
+ if (m_bHaveCommandFileNamePathOnCmdLine)
+ {
+ std::ifstream startScript(m_strCmdLineArgCommandFileNamePath.c_str());
+ if (!startScript.is_open())
+ {
+ m_bExitApp = true;
+ const CMIUtilString errMsg(
+ CMIUtilString::Format(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN), m_strCmdLineArgCommandFileNamePath.c_str()));
+ SetErrorDescription(errMsg.c_str());
+ bOk = MIstatus::failure;
+ }
+ else
+ {
+ CMIUtilString executedCommand;
+ while (std::getline(startScript, executedCommand))
+ {
+ bOk = QueueMICommand(executedCommand);
+ if (!bOk)
+ {
+ m_bExitApp = true;
+ bOk = MIstatus::failure;
+ break;
+ }
+ }
+ }
+ }
+
// While the app is active
while (!m_bExitApp)
{
@@ -643,7 +695,7 @@
// Ensure that a new line is sent as the last act of the dying driver
m_rStdOut.WriteMIResponse("\n", false);
- return MIstatus::success;
+ return bOk;
}
//++ ------------------------------------------------------------------------------------
@@ -977,6 +1029,25 @@
return bOk;
}
+// Helper function for CMIDriver::InterpretCommandThisDriver.
+// Turn the string into something that can be embedded in a string.
+static std::string
+stringify(const std::string &s)
+{
+ std::string result;
+ result.reserve(s.length() + 2);
+ result += '"';
+ const std::string::const_iterator last = s.end();
+ for (std::string::const_iterator p = s.begin(); p != last; ++p)
+ {
+ if (*p == '"' || *p == '\\')
+ result += '\\';
+ result += *p;
+ }
+ result += '"';
+ return result;
+}
+
//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. If a
@@ -985,7 +1056,7 @@
// This function is used by the application's main thread.
// Type: Method.
// Args: vTextLine - (R) Text data representing a possible command.
-// vwbCmdYesValid - (W) True = Command invalid, false = command acted on.
+// vwbCmdYesValid - (W) True = Command valid, false = command not handled.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
@@ -993,12 +1064,29 @@
bool
CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid)
{
+ // Make sure we have a valid MI command
+ CMIUtilString vMITextLine(vTextLine);
+ if (vTextLine.at(0) != '-')
+ {
+ static const CMIUtilString strTargetCreate("target create ");
+ if (vTextLine.compare(0, strTargetCreate.size(), strTargetCreate) == 0)
+ {
+ // Replace 'target create <file>' with '-file-exec-and-symbols <file>'.
+ vMITextLine = "-file-exec-and-symbols ";
+ vMITextLine.append(vTextLine.begin() + strTargetCreate.size(), vTextLine.end());
+ }
+ else
+ {
+ // Wrap non-MI commands to make them MI-compatible.
+ vMITextLine = "-interpreter-exec command " + stringify(vTextLine);
+ }
+ }
+
vwbCmdYesValid = false;
-
bool bCmdNotInCmdFactor = false;
SMICmdData cmdData;
CMICmdMgr &rCmdMgr = CMICmdMgr::Instance();
- if (!rCmdMgr.CmdInterpret(vTextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData))
+ if (!rCmdMgr.CmdInterpret(vMITextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData))
return MIstatus::failure;
if (vwbCmdYesValid)
@@ -1012,12 +1100,12 @@
// Check for escape character, may be cursor control characters
// This code is not necessary for application operation, just want to keep tabs on what
// is been given to the driver to try and intepret.
- if (vTextLine.at(0) == 27)
+ if (vMITextLine.at(0) == 27)
{
CMIUtilString logInput(MIRSRC(IDS_STDIN_INPUT_CTRL_CHARS));
- for (MIuint i = 0; i < vTextLine.length(); i++)
+ for (MIuint i = 0; i < vMITextLine.length(); i++)
{
- logInput += CMIUtilString::Format("%d ", vTextLine.at(i));
+ logInput += CMIUtilString::Format("%d ", vMITextLine.at(i));
}
m_pLog->WriteLog(logInput);
return MIstatus::success;
@@ -1030,7 +1118,7 @@
strNotInCmdFactory = CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_NOT_IN_FACTORY), cmdData.strMiCmd.c_str());
const CMIUtilString strNot(CMIUtilString::Format("%s ", MIRSRC(IDS_WORD_NOT)));
const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_RECEIVED), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str()));
+ CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_RECEIVED), vMITextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str()));
const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg);
const CMICmnMIValueResult valueResult("msg", vconst);
const CMICmnMIResultRecord miResultRecord(cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult);
Index: tools/lldb-mi/MIDriver.h
===================================================================
--- tools/lldb-mi/MIDriver.h (revision 222209)
+++ tools/lldb-mi/MIDriver.h (working copy)
@@ -175,8 +175,10 @@
CMICmnLLDBDebugger &m_rLldbDebugger;
CMICmnStreamStdout &m_rStdOut;
DriverState_e m_eCurrentDriverState;
- bool m_bHaveExecutableFileNamePathOnCmdLine; // True = Yes executable given as one of the parameters to the MI Driver, false = not found
+ bool m_bHaveExecutableFileNamePathOnCmdLine; // True = yes, executable given as one of the parameters to the MI Driver, false = not found
CMIUtilString m_strCmdLineArgExecuteableFileNamePath;
- bool m_bDriverDebuggingArgExecutable; // True = The MI Driver (MI mode) is debugging executable passed as argument, false = running via
- // a client i.e Eclipse
+ bool m_bDriverDebuggingArgExecutable; // True = the MI Driver (MI mode) is debugging executable passed as argument,
+ // false = running via a client (e.g. Eclipse)
+ bool m_bHaveCommandFileNamePathOnCmdLine; // True = file with initial commands given as one of the parameters to the MI Driver, false = not found
+ CMIUtilString m_strCmdLineArgCommandFileNamePath;
};
More information about the lldb-commits
mailing list