1 //===-- MICmdCmdGdbSet.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Overview: CMICmdCmdGdbSet implementation.
13 #include "MICmdCmdGdbSet.h"
14 #include "MICmdArgValListOfN.h"
15 #include "MICmdArgValOptionLong.h"
16 #include "MICmdArgValString.h"
17 #include "MICmnLLDBDebugSessionInfo.h"
18 #include "MICmnMIResultRecord.h"
19 #include "MICmnMIValueConst.h"
22 const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t
23 CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr = {
24 {"target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync},
25 {"print", &CMICmdCmdGdbSet::OptionFnPrint},
26 // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, //
27 // Example code if need to implement GDB set other options
28 {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix},
29 {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath},
30 {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}};
33 //------------------------------------------------------------------------------------
34 // Details: CMICmdCmdGdbSet constructor.
40 CMICmdCmdGdbSet::CMICmdCmdGdbSet()
41 : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
42 m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
43 m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
44 // Command factory matches this name with that received from the stdin stream
45 m_strMiCmd = "gdb-set";
47 // Required by the CMICmdFactory when registering *this command
48 m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
52 //------------------------------------------------------------------------------------
53 // Details: CMICmdCmdGdbSet destructor.
54 // Type: Overrideable.
59 CMICmdCmdGdbSet::~CMICmdCmdGdbSet() {}
62 //------------------------------------------------------------------------------------
63 // Details: The invoker requires this function. The parses the command line
65 // arguments to extract values for each of those arguments.
68 // Return: MIstatus::success - Functional succeeded.
69 // MIstatus::failure - Functional failed.
72 bool CMICmdCmdGdbSet::ParseArgs() {
73 m_setCmdArgs.Add(new CMICmdArgValListOfN(
74 m_constStrArgNamedGdbOption, true, true,
75 CMICmdArgValListBase::eArgValType_StringAnything));
76 return ParseValidateCmdOptions();
80 //------------------------------------------------------------------------------------
81 // Details: The invoker requires this function. The command is executed in this
83 // The command is likely to communicate with the LLDB SBDebugger in
87 // Return: MIstatus::success - Functional succeeded.
88 // MIstatus::failure - Functional failed.
91 bool CMICmdCmdGdbSet::Execute() {
92 CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
93 const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
94 pArgGdbOption->GetExpectedOptions());
96 // Get the gdb-set option to carry out. This option will be used as an action
97 // which should be done. Further arguments will be used as parameters for it.
98 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
99 const CMICmdArgValString *pOption =
100 static_cast<const CMICmdArgValString *>(*it);
101 const CMIUtilString strOption(pOption->GetValue());
104 // Retrieve the parameter(s) for the option
105 CMIUtilString::VecString_t vecWords;
106 while (it != rVecWords.end()) {
107 const CMICmdArgValString *pWord =
108 static_cast<const CMICmdArgValString *>(*it);
109 vecWords.push_back(pWord->GetValue());
115 FnGdbOptionPtr pPrintRequestFn = nullptr;
116 if (!GetOptionFn(strOption, pPrintRequestFn)) {
117 // For unimplemented option handlers, fallback on a generic handler
118 // ToDo: Remove this when ALL options have been implemented
119 if (!GetOptionFn("fallback", pPrintRequestFn)) {
120 m_bGdbOptionRecognised = false;
121 m_strGdbOptionName = "fallback"; // This would be the strOption name
122 return MIstatus::success;
126 m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
127 if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
128 return MIstatus::failure;
130 return MIstatus::success;
134 //------------------------------------------------------------------------------------
135 // Details: The invoker requires this function. The command prepares a MI Record
137 // for the work carried out in the Execute() method.
140 // Return: MIstatus::success - Functional succeeded.
141 // MIstatus::failure - Functional failed.
144 bool CMICmdCmdGdbSet::Acknowledge() {
145 // Print error if option isn't recognized:
146 // ^error,msg="The request '%s' was not recognized, not implemented"
147 if (!m_bGdbOptionRecognised) {
148 const CMICmnMIValueConst miValueConst(
149 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
150 m_strGdbOptionName.c_str()));
151 const CMICmnMIValueResult miValueResult("msg", miValueConst);
152 const CMICmnMIResultRecord miRecordResult(
153 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
155 m_miResultRecord = miRecordResult;
156 return MIstatus::success;
160 if (m_bGdbOptionFnSuccessful) {
161 const CMICmnMIResultRecord miRecordResult(
162 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
163 m_miResultRecord = miRecordResult;
164 return MIstatus::success;
167 // Print error if request failed:
168 // ^error,msg="The request '%s' failed.
169 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
170 MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
171 const CMICmnMIValueResult miValueResult("msg", miValueConst);
172 const CMICmnMIResultRecord miRecordResult(
173 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
175 m_miResultRecord = miRecordResult;
177 return MIstatus::success;
181 //------------------------------------------------------------------------------------
182 // Details: Required by the CMICmdFactory when registering *this command. The
184 // calls this function to create an instance of *this command.
185 // Type: Static method.
187 // Return: CMICmdBase * - Pointer to a new command.
190 CMICmdBase *CMICmdCmdGdbSet::CreateSelf() { return new CMICmdCmdGdbSet(); }
193 //------------------------------------------------------------------------------------
194 // Details: Retrieve the print function's pointer for the matching print
197 // Args: vrPrintFnName - (R) The info requested.
198 // vrwpFn - (W) The print function's pointer of the function
200 // Return: bool - True = Print request is implemented, false = not found.
203 bool CMICmdCmdGdbSet::GetOptionFn(const CMIUtilString &vrPrintFnName,
204 FnGdbOptionPtr &vrwpFn) const {
207 const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
208 ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
209 if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
210 vrwpFn = (*it).second;
218 //------------------------------------------------------------------------------------
219 // Details: Carry out work to complete the GDB set option 'target-async' to
221 // and send back information asked for.
223 // Args: vrWords - (R) List of additional parameters used by this option.
224 // Return: MIstatus::success - Function succeeded.
225 // MIstatus::failure - Function failed.
228 bool CMICmdCmdGdbSet::OptionFnTargetAsync(
229 const CMIUtilString::VecString_t &vrWords) {
230 bool bAsyncMode = false;
233 if (vrWords.size() > 1)
234 // Too many arguments.
236 else if (vrWords.size() == 0)
237 // If no arguments, default is "on".
239 else if (CMIUtilString::Compare(vrWords[0], "on"))
241 else if (CMIUtilString::Compare(vrWords[0], "off"))
244 // Unrecognized argument.
249 m_bGbbOptionFnHasError = true;
250 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC);
251 return MIstatus::failure;
254 // Turn async mode on/off.
255 CMICmnLLDBDebugSessionInfo &rSessionInfo(
256 CMICmnLLDBDebugSessionInfo::Instance());
257 rSessionInfo.GetDebugger().SetAsync(bAsyncMode);
259 return MIstatus::success;
263 //------------------------------------------------------------------------------------
264 // Details: Carry out work to complete the GDB set option
265 // 'print-char-array-as-string' to
266 // prepare and send back information asked for.
268 // Args: vrWords - (R) List of additional parameters used by this option.
269 // Return: MIstatus::success - Function succeeded.
270 // MIstatus::failure - Function failed.
273 bool CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) {
274 const bool bAllArgs(vrWords.size() == 2);
275 const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") ||
276 CMIUtilString::Compare(vrWords[1], "1")));
277 const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") ||
278 CMIUtilString::Compare(vrWords[1], "0")));
279 if (!bAllArgs || (!bArgOn && !bArgOff)) {
280 m_bGbbOptionFnHasError = true;
281 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS);
282 return MIstatus::failure;
285 const CMIUtilString strOption(vrWords[0]);
286 CMIUtilString strOptionKey;
287 if (CMIUtilString::Compare(strOption, "char-array-as-string"))
288 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
289 else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
290 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
291 else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
292 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
294 m_bGbbOptionFnHasError = true;
295 m_strGdbOptionFnError = CMIUtilString::Format(
296 MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
297 return MIstatus::failure;
300 const bool bOptionValue(bArgOn);
301 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey,
303 m_bGbbOptionFnHasError = false;
304 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
305 m_cmdData.strMiCmd.c_str(),
306 strOptionKey.c_str()));
307 return MIstatus::failure;
310 return MIstatus::success;
314 //------------------------------------------------------------------------------------
315 // Details: Carry out work to complete the GDB set option 'solib-search-path' to
317 // and send back information asked for.
319 // Args: vrWords - (R) List of additional parameters used by this option.
320 // Return: MIstatus::success - Functional succeeded.
321 // MIstatus::failure - Functional failed.
324 bool CMICmdCmdGdbSet::OptionFnSolibSearchPath(
325 const CMIUtilString::VecString_t &vrWords) {
326 // Check we have at least one argument
327 if (vrWords.size() < 1) {
328 m_bGbbOptionFnHasError = true;
329 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
330 return MIstatus::failure;
332 const CMIUtilString &rStrValSolibPath(vrWords[0]);
334 // Add 'solib-search-path' to the shared data list
335 const CMIUtilString &rStrKeySolibPath(
336 m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath);
337 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeySolibPath,
339 m_bGbbOptionFnHasError = false;
340 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
341 m_cmdData.strMiCmd.c_str(),
342 rStrKeySolibPath.c_str()));
343 return MIstatus::failure;
346 return MIstatus::success;
350 //------------------------------------------------------------------------------------
351 // Details: Carry out work to complete the GDB set option 'output-radix' to
353 // and send back information asked for.
355 // Args: vrWords - (R) List of additional parameters used by this option.
356 // Return: MIstatus::success - Functional succeeded.
357 // MIstatus::failure - Functional failed.
360 bool CMICmdCmdGdbSet::OptionFnOutputRadix(
361 const CMIUtilString::VecString_t &vrWords) {
362 // Check we have at least one argument
363 if (vrWords.size() < 1) {
364 m_bGbbOptionFnHasError = true;
365 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
366 return MIstatus::failure;
368 const CMIUtilString &rStrValOutputRadix(vrWords[0]);
370 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format =
371 CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
373 if (rStrValOutputRadix.ExtractNumber(radix)) {
376 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal;
379 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural;
382 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex;
385 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
389 if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) {
390 m_bGbbOptionFnHasError = false;
391 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
392 m_cmdData.strMiCmd.c_str(), "Output Radix"));
393 return MIstatus::failure;
395 CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format);
397 return MIstatus::success;
401 //------------------------------------------------------------------------------------
402 // Details: Carry out work to complete the GDB set option to prepare and send
404 // requested information.
407 // Return: MIstatus::success - Functional succeeded.
408 // MIstatus::failure - Functional failed.
411 bool CMICmdCmdGdbSet::OptionFnFallback(
412 const CMIUtilString::VecString_t &vrWords) {
415 // Do nothing - intentional. This is a fallback function to do nothing.
416 // This allows the search for gdb-set options to always succeed when the
418 // found (implemented).
420 return MIstatus::success;