1 //===-- MICmdCmdVar.cpp -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Overview: CMICmdCmdVarCreate implementation.
10 // CMICmdCmdVarUpdate implementation.
11 // CMICmdCmdVarDelete implementation.
12 // CMICmdCmdVarAssign implementation.
13 // CMICmdCmdVarSetFormat implementation.
14 // CMICmdCmdVarListChildren implementation.
15 // CMICmdCmdVarEvaluateExpression implementation.
16 // CMICmdCmdVarInfoPathExpression implementation.
17 // CMICmdCmdVarShowAttributes implementation.
19 // Third Party Headers:
20 #include "lldb/API/SBStream.h"
21 #include "lldb/API/SBThread.h"
22 #include "lldb/API/SBType.h"
25 #include "MICmdArgValListOfN.h"
26 #include "MICmdArgValNumber.h"
27 #include "MICmdArgValOptionLong.h"
28 #include "MICmdArgValOptionShort.h"
29 #include "MICmdArgValPrintValues.h"
30 #include "MICmdArgValString.h"
31 #include "MICmdArgValThreadGrp.h"
32 #include "MICmdCmdVar.h"
33 #include "MICmnLLDBDebugSessionInfo.h"
34 #include "MICmnLLDBDebugger.h"
35 #include "MICmnLLDBProxySBValue.h"
36 #include "MICmnLLDBUtilSBValue.h"
37 #include "MICmnMIResultRecord.h"
38 #include "MICmnMIValueConst.h"
43 // Details: CMICmdCmdVarCreate constructor.
49 CMICmdCmdVarCreate::CMICmdCmdVarCreate()
50 : m_nChildren(0), m_nThreadId(0), m_strType("??"), m_bValid(false),
51 m_strValue("??"), m_constStrArgName("name"),
52 m_constStrArgFrameAddr("frame-addr"),
53 m_constStrArgExpression("expression") {
54 // Command factory matches this name with that received from the stdin stream
55 m_strMiCmd = "var-create";
57 // Required by the CMICmdFactory when registering *this command
58 m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
62 // Details: CMICmdCmdVarCreate destructor.
63 // Type: Overrideable.
68 CMICmdCmdVarCreate::~CMICmdCmdVarCreate() {}
71 // Details: The invoker requires this function. The parses the command line
73 // arguments to extract values for each of those arguments.
76 // Return: MIstatus::success - Functional succeeded.
77 // MIstatus::failure - Functional failed.
80 bool CMICmdCmdVarCreate::ParseArgs() {
81 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
82 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
84 new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
85 return ParseValidateCmdOptions();
89 // Details: The invoker requires this function. The command does work in this
91 // The command is likely to communicate with the LLDB SBDebugger in
95 // Return: MIstatus::success - Functional succeeded.
96 // MIstatus::failure - Functional failed.
99 bool CMICmdCmdVarCreate::Execute() {
100 CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
101 CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
102 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
103 CMICMDBASE_GETOPTION(pArgFrameAddr, String, m_constStrArgFrameAddr);
104 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
106 // Retrieve the --thread option's thread ID (only 1)
107 MIuint64 nThreadId = UINT64_MAX;
108 if (pArgThread->GetFound() &&
109 !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
110 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
111 m_cmdData.strMiCmd.c_str(),
112 m_constStrArgThread.c_str()));
113 return MIstatus::failure;
116 // Retrieve the --frame option's number
117 MIuint64 nFrame = UINT64_MAX;
118 if (pArgThread->GetFound() &&
119 !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
120 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
121 m_cmdData.strMiCmd.c_str(),
122 m_constStrArgFrame.c_str()));
123 return MIstatus::failure;
126 const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(
127 pArgFrame->GetExpectedOptions());
128 CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 =
130 if (it2 != rVecFrameId.end()) {
131 const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
132 nFrame = pOption->GetValue();
135 m_strVarName = "<unnamedvariable>";
136 if (pArgName->GetFound()) {
137 const CMIUtilString &rArg = pArgName->GetValue();
138 const bool bAutoName = (rArg == "-");
140 m_strVarName = CMIUtilString::Format(
141 "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
142 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
147 bool bCurrentFrame = false;
148 if (pArgFrameAddr->GetFound()) {
149 const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
150 bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
151 if (!bCurrentFrame && (nFrame == UINT64_MAX)) {
152 // FIXME: *addr isn't implemented. Exit with error if --thread isn't
154 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
155 m_cmdData.strMiCmd.c_str(),
156 m_constStrArgFrame.c_str()));
157 return MIstatus::failure;
161 const CMIUtilString &rStrExpression(pArgExpression->GetValue());
162 m_strExpression = rStrExpression;
164 CMICmnLLDBDebugSessionInfo &rSessionInfo(
165 CMICmnLLDBDebugSessionInfo::Instance());
166 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
167 lldb::SBThread thread = (nThreadId != UINT64_MAX)
168 ? sbProcess.GetThreadByIndexID(nThreadId)
169 : sbProcess.GetSelectedThread();
170 m_nThreadId = thread.GetIndexID();
171 lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame()
172 : thread.GetFrameAtIndex(nFrame);
175 if (rStrExpression[0] == '$') {
176 const CMIUtilString rStrRegister(rStrExpression.substr(1));
177 value = frame.FindRegister(rStrRegister.c_str());
179 const bool bArgs = true;
180 const bool bLocals = true;
181 const bool bStatics = true;
182 const bool bInScopeOnly = true;
183 const lldb::SBValueList valueList =
184 frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
185 value = valueList.GetFirstValueByName(rStrExpression.c_str());
188 if (!value.IsValid())
189 value = frame.EvaluateExpression(rStrExpression.c_str());
191 if (value.IsValid() && value.GetError().Success()) {
192 CompleteSBValue(value);
194 m_nChildren = value.GetNumChildren();
195 m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
197 // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
199 CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName,
201 m_strValue = varObj.GetValueFormatted();
203 m_strValue = value.GetError().GetCString();
206 return MIstatus::success;
210 // Details: The invoker requires this function. The command prepares a MI Record
212 // for the work carried out in the Execute().
215 // Return: MIstatus::success - Functional succeeded.
216 // MIstatus::failure - Functional failed.
219 bool CMICmdCmdVarCreate::Acknowledge() {
222 // "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
223 const CMICmnMIValueConst miValueConst(m_strVarName);
224 CMICmnMIValueResult miValueResultAll("name", miValueConst);
225 const CMIUtilString strNumChild(CMIUtilString::Format("%d", m_nChildren));
226 const CMICmnMIValueConst miValueConst2(strNumChild);
227 miValueResultAll.Add("numchild", miValueConst2);
228 const CMICmnMIValueConst miValueConst3(m_strValue);
229 miValueResultAll.Add("value", miValueConst3);
230 const CMICmnMIValueConst miValueConst4(m_strType);
231 miValueResultAll.Add("type", miValueConst4);
232 const CMIUtilString strThreadId(CMIUtilString::Format("%llu", m_nThreadId));
233 const CMICmnMIValueConst miValueConst5(strThreadId);
234 miValueResultAll.Add("thread-id", miValueConst5);
235 const CMICmnMIValueConst miValueConst6("0");
236 miValueResultAll.Add("has_more", miValueConst6);
238 const CMICmnMIResultRecord miRecordResult(
239 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
241 m_miResultRecord = miRecordResult;
243 return MIstatus::success;
246 CMIUtilString strErrMsg(m_strValue);
247 if (m_strValue.empty())
248 strErrMsg = CMIUtilString::Format(
249 MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
250 const CMICmnMIValueConst miValueConst(
251 strErrMsg.Escape(true /* vbEscapeQuotes */));
252 CMICmnMIValueResult miValueResult("msg", miValueConst);
253 const CMICmnMIResultRecord miRecordResult(
254 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
256 m_miResultRecord = miRecordResult;
258 return MIstatus::success;
262 // Details: Required by the CMICmdFactory when registering *this command. The
264 // calls this function to create an instance of *this command.
265 // Type: Static method.
267 // Return: CMICmdBase * - Pointer to a new command.
270 CMICmdBase *CMICmdCmdVarCreate::CreateSelf() {
271 return new CMICmdCmdVarCreate();
275 // Details: Complete SBValue object and its children to get
276 // SBValue::GetValueDidChange
279 // Args: vrwValue - (R) Value to update.
280 // Return: MIstatus::success - Functional succeeded.
281 // MIstatus::failure - Functional failed.
284 void CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue) {
285 // Force a value to update
286 vrwValue.GetValueDidChange();
288 // And update its children
289 lldb::SBType valueType = vrwValue.GetType();
290 if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
291 const MIuint nChildren = vrwValue.GetNumChildren();
292 for (MIuint i = 0; i < nChildren; ++i) {
293 lldb::SBValue member = vrwValue.GetChildAtIndex(i);
294 if (member.IsValid())
295 CompleteSBValue(member);
302 // Details: CMICmdCmdVarUpdate constructor.
308 CMICmdCmdVarUpdate::CMICmdCmdVarUpdate()
309 : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
310 m_bValueChanged(false), m_miValueList(true) {
311 // Command factory matches this name with that received from the stdin stream
312 m_strMiCmd = "var-update";
314 // Required by the CMICmdFactory when registering *this command
315 m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
319 // Details: CMICmdCmdVarUpdate destructor.
320 // Type: Overrideable.
325 CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate() {}
328 // Details: The invoker requires this function. The parses the command line
330 // arguments to extract values for each of those arguments.
333 // Return: MIstatus::success - Functional succeeded.
334 // MIstatus::failure - Functional failed.
337 bool CMICmdCmdVarUpdate::ParseArgs() {
339 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
340 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
341 return ParseValidateCmdOptions();
345 // Details: The invoker requires this function. The command does work in this
347 // The command is likely to communicate with the LLDB SBDebugger in
351 // Return: MIstatus::success - Functional succeeded.
352 // MIstatus::failure - Functional failed.
355 bool CMICmdCmdVarUpdate::Execute() {
356 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
357 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
359 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
360 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
361 if (pArgPrintValues->GetFound())
363 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
364 pArgPrintValues->GetValue());
366 const CMIUtilString &rVarObjName(pArgName->GetValue());
367 CMICmnLLDBDebugSessionInfoVarObj varObj;
368 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
369 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
370 m_cmdData.strMiCmd.c_str(),
371 rVarObjName.c_str()));
372 return MIstatus::failure;
375 lldb::SBValue &rValue = varObj.GetValue();
376 if (!ExamineSBValueForChange(rValue, m_bValueChanged))
377 return MIstatus::failure;
379 if (m_bValueChanged) {
380 varObj.UpdateValue();
381 const bool bPrintValue(
383 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
385 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
386 rValue.GetNumChildren() == 0));
387 const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
388 const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
389 MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr,
393 return MIstatus::success;
397 // Details: The invoker requires this function. The command prepares a MI Record
399 // for the work carried out in the Execute().
402 // Return: MIstatus::success - Functional succeeded.
403 // MIstatus::failure - Functional failed.
406 bool CMICmdCmdVarUpdate::Acknowledge() {
407 if (m_bValueChanged) {
409 // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
410 CMICmnMIValueResult miValueResult("changelist", m_miValueList);
411 const CMICmnMIResultRecord miRecordResult(
412 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
414 m_miResultRecord = miRecordResult;
416 // MI print "%s^done,changelist=[]"
417 const CMICmnMIValueList miValueList(true);
418 CMICmnMIValueResult miValueResult6("changelist", miValueList);
419 const CMICmnMIResultRecord miRecordResult(
420 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
422 m_miResultRecord = miRecordResult;
425 return MIstatus::success;
429 // Details: Required by the CMICmdFactory when registering *this command. The
431 // calls this function to create an instance of *this command.
432 // Type: Static method.
434 // Return: CMICmdBase * - Pointer to a new command.
437 CMICmdBase *CMICmdCmdVarUpdate::CreateSelf() {
438 return new CMICmdCmdVarUpdate();
442 // Details: Form the MI response for multiple variables.
444 // Args: vrStrVarName - (R) Session var object's name.
445 // vpValue - (R) Text version of the value held in the
447 // vrStrScope - (R) In scope "yes" or "no".
451 void CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName,
452 const char *const vpValue,
453 const CMIUtilString &vrStrScope) {
455 // "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
456 const CMICmnMIValueConst miValueConst(vrStrVarName);
457 const CMICmnMIValueResult miValueResult("name", miValueConst);
458 CMICmnMIValueTuple miValueTuple(miValueResult);
459 if (vpValue != nullptr) {
460 const CMICmnMIValueConst miValueConst2(vpValue);
461 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
462 miValueTuple.Add(miValueResult2);
464 const CMICmnMIValueConst miValueConst3(vrStrScope);
465 const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
466 miValueTuple.Add(miValueResult3);
467 const CMICmnMIValueConst miValueConst4("false");
468 const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
469 miValueTuple.Add(miValueResult4);
470 const CMICmnMIValueConst miValueConst5("0");
471 const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
472 miValueTuple.Add(miValueResult5);
473 m_miValueList.Add(miValueTuple);
477 // Details: Determine if the var object was changed.
479 // Args: vrVarObj - (R) Session var object to examine.
480 // vrwbChanged - (W) True = The var object was changed,
481 // False = It was not changed.
482 // Return: MIstatus::success - Functional succeeded.
483 // MIstatus::failure - Functional failed.
486 bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
488 if (vrwValue.GetValueDidChange()) {
490 return MIstatus::success;
493 const MIuint nChildren = vrwValue.GetNumChildren();
494 for (MIuint i = 0; i < nChildren; ++i) {
495 lldb::SBValue member = vrwValue.GetChildAtIndex(i);
496 if (!member.IsValid())
499 // skip pointers and references to avoid infinite loop
500 if (member.GetType().GetTypeFlags() &
501 (lldb::eTypeIsPointer | lldb::eTypeIsReference))
504 // Handle composite types (i.e. struct or arrays)
505 if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
506 return MIstatus::success;
509 return MIstatus::success;
514 // Details: CMICmdCmdVarDelete constructor.
520 CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
521 // Command factory matches this name with that received from the stdin stream
522 m_strMiCmd = "var-delete";
524 // Required by the CMICmdFactory when registering *this command
525 m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
529 // Details: The invoker requires this function. The parses the command line
531 // arguments to extract values for each of those arguments.
534 // Return: MIstatus::success - Functional succeeded.
535 // MIstatus::failure - Functional failed.
538 bool CMICmdCmdVarDelete::ParseArgs() {
539 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
540 return ParseValidateCmdOptions();
544 // Details: CMICmdCmdVarDelete destructor.
545 // Type: Overrideable.
550 CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
553 // Details: The invoker requires this function. The command does work in this
555 // The command is likely to communicate with the LLDB SBDebugger in
559 // Return: MIstatus::success - Functional succeeded.
560 // MIstatus::failure - Functional failed.
563 bool CMICmdCmdVarDelete::Execute() {
564 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
566 const CMIUtilString &rVarObjName(pArgName->GetValue());
567 CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
569 return MIstatus::success;
573 // Details: The invoker requires this function. The command prepares a MI Record
575 // for the work carried out in the Execute().
578 // Return: MIstatus::success - Functional succeeded.
579 // MIstatus::failure - Functional failed.
582 bool CMICmdCmdVarDelete::Acknowledge() {
583 const CMICmnMIResultRecord miRecordResult(
584 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
585 m_miResultRecord = miRecordResult;
587 return MIstatus::success;
591 // Details: Required by the CMICmdFactory when registering *this command. The
593 // calls this function to create an instance of *this command.
594 // Type: Static method.
596 // Return: CMICmdBase * - Pointer to a new command.
599 CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
600 return new CMICmdCmdVarDelete();
605 // Details: CMICmdCmdVarAssign constructor.
611 CMICmdCmdVarAssign::CMICmdCmdVarAssign()
612 : m_bOk(true), m_constStrArgName("name"),
613 m_constStrArgExpression("expression") {
614 // Command factory matches this name with that received from the stdin stream
615 m_strMiCmd = "var-assign";
617 // Required by the CMICmdFactory when registering *this command
618 m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
622 // Details: CMICmdCmdVarAssign destructor.
623 // Type: Overrideable.
628 CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
631 // Details: The invoker requires this function. The parses the command line
633 // arguments to extract values for each of those arguments.
636 // Return: MIstatus::success - Functional succeeded.
637 // MIstatus::failure - Functional failed.
640 bool CMICmdCmdVarAssign::ParseArgs() {
641 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
642 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
643 return ParseValidateCmdOptions();
647 // Details: The invoker requires this function. The command does work in this
649 // The command is likely to communicate with the LLDB SBDebugger in
653 // Return: MIstatus::success - Functional succeeded.
654 // MIstatus::failure - Functional failed.
657 bool CMICmdCmdVarAssign::Execute() {
658 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
659 CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
661 const CMIUtilString &rVarObjName(pArgName->GetValue());
662 const CMIUtilString &rExpression(pArgExpression->GetValue());
664 CMICmnLLDBDebugSessionInfoVarObj varObj;
665 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
666 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
667 m_cmdData.strMiCmd.c_str(),
668 rVarObjName.c_str()));
669 return MIstatus::failure;
671 m_varObjName = rVarObjName;
673 CMIUtilString strExpression(rExpression.Trim());
674 strExpression = strExpression.Trim('"');
675 lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
676 m_bOk = rValue.SetValueFromCString(strExpression.c_str());
678 varObj.UpdateValue();
680 return MIstatus::success;
684 // Details: The invoker requires this function. The command prepares a MI Record
686 // for the work carried out in the Execute().
689 // Return: MIstatus::success - Functional succeeded.
690 // MIstatus::failure - Functional failed.
693 bool CMICmdCmdVarAssign::Acknowledge() {
695 // MI print "%s^done,value=\"%s\""
696 CMICmnLLDBDebugSessionInfoVarObj varObj;
697 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
698 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
699 const CMICmnMIValueResult miValueResult("value", miValueConst);
700 const CMICmnMIResultRecord miRecordResult(
701 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
703 m_miResultRecord = miRecordResult;
705 return MIstatus::success;
708 const CMICmnMIValueConst miValueConst("expression could not be evaluated");
709 const CMICmnMIValueResult miValueResult("msg", miValueConst);
710 const CMICmnMIResultRecord miRecordResult(
711 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
713 m_miResultRecord = miRecordResult;
715 return MIstatus::success;
719 // Details: Required by the CMICmdFactory when registering *this command. The
721 // calls this function to create an instance of *this command.
722 // Type: Static method.
724 // Return: CMICmdBase * - Pointer to a new command.
727 CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
728 return new CMICmdCmdVarAssign();
733 // Details: CMICmdCmdVarSetFormat constructor.
739 CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
740 : m_constStrArgName("name"), m_constStrArgFormatSpec("format-spec") {
741 // Command factory matches this name with that received from the stdin stream
742 m_strMiCmd = "var-set-format";
744 // Required by the CMICmdFactory when registering *this command
745 m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
749 // Details: CMICmdCmdVarSetFormat destructor.
750 // Type: Overrideable.
755 CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
758 // Details: The invoker requires this function. The parses the command line
760 // arguments to extract values for each of those arguments.
763 // Return: MIstatus::success - Functional succeeded.
764 // MIstatus::failure - Functional failed.
767 bool CMICmdCmdVarSetFormat::ParseArgs() {
768 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
769 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
770 return ParseValidateCmdOptions();
774 // Details: The invoker requires this function. The command does work in this
776 // The command is likely to communicate with the LLDB SBDebugger in
780 // Return: MIstatus::success - Functional succeeded.
781 // MIstatus::failure - Functional failed.
784 bool CMICmdCmdVarSetFormat::Execute() {
785 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
786 CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
788 const CMIUtilString &rVarObjName(pArgName->GetValue());
789 const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
791 CMICmnLLDBDebugSessionInfoVarObj varObj;
792 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
793 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
794 m_cmdData.strMiCmd.c_str(),
795 rVarObjName.c_str()));
796 return MIstatus::failure;
798 if (!varObj.SetVarFormat(
799 CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
801 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID),
802 m_cmdData.strMiCmd.c_str(),
803 rVarObjName.c_str(), rExpression.c_str()));
804 return MIstatus::failure;
806 varObj.UpdateValue();
808 m_varObjName = rVarObjName;
810 return MIstatus::success;
814 // Details: The invoker requires this function. The command prepares a MI Record
816 // for the work carried out in the Execute().
819 // Return: MIstatus::success - Functional succeeded.
820 // MIstatus::failure - Functional failed.
823 bool CMICmdCmdVarSetFormat::Acknowledge() {
825 // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
826 CMICmnLLDBDebugSessionInfoVarObj varObj;
827 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
828 const CMICmnMIValueConst miValueConst(m_varObjName);
829 const CMICmnMIValueResult miValueResult("name", miValueConst);
830 CMICmnMIValueTuple miValueTuple(miValueResult);
831 const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
832 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
833 miValueTuple.Add(miValueResult2);
834 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
835 const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
836 const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
837 miValueTuple.Add(miValueResult3);
838 const CMICmnMIValueConst miValueConst4("false");
839 const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
840 miValueTuple.Add(miValueResult4);
841 const CMICmnMIValueConst miValueConst5("0");
842 const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
843 miValueTuple.Add(miValueResult5);
844 const CMICmnMIValueList miValueList(miValueTuple);
845 const CMICmnMIValueResult miValueResult6("changelist", miValueList);
847 const CMICmnMIResultRecord miRecordResult(
848 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
850 m_miResultRecord = miRecordResult;
852 return MIstatus::success;
856 // Details: Required by the CMICmdFactory when registering *this command. The
858 // calls this function to create an instance of *this command.
859 // Type: Static method.
861 // Return: CMICmdBase * - Pointer to a new command.
864 CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
865 return new CMICmdCmdVarSetFormat();
870 // Details: CMICmdCmdVarListChildren constructor.
876 CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
877 : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
878 m_constStrArgFrom("from"), m_constStrArgTo("to"), m_bValueValid(false),
879 m_nChildren(0), m_miValueList(true), m_bHasMore(false) {
880 // Command factory matches this name with that received from the stdin stream
881 m_strMiCmd = "var-list-children";
883 // Required by the CMICmdFactory when registering *this command
884 m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
888 // Details: CMICmdCmdVarListChildren destructor.
889 // Type: Overrideable.
894 CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
897 // Details: The invoker requires this function. The parses the command line
899 // arguments to extract values for each of those arguments.
902 // Return: MIstatus::success - Functional succeeded.
903 // MIstatus::failure - Functional failed.
906 bool CMICmdCmdVarListChildren::ParseArgs() {
908 new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
909 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
910 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
911 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
912 return ParseValidateCmdOptions();
916 // Details: The invoker requires this function. The command does work in this
918 // The command is likely to communicate with the LLDB SBDebugger in
922 // Return: MIstatus::success - Functional succeeded.
923 // MIstatus::failure - Functional failed.
926 bool CMICmdCmdVarListChildren::Execute() {
927 CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
928 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
929 CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
930 CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
932 CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
933 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
934 if (pArgPrintValues->GetFound())
936 static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
937 pArgPrintValues->GetValue());
939 const CMIUtilString &rVarObjName(pArgName->GetValue());
940 CMICmnLLDBDebugSessionInfoVarObj varObj;
941 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
942 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
943 m_cmdData.strMiCmd.c_str(),
944 rVarObjName.c_str()));
945 return MIstatus::failure;
949 MIuint nTo = UINT32_MAX;
950 if (pArgFrom->GetFound() && pArgTo->GetFound()) {
951 nFrom = pArgFrom->GetValue();
952 nTo = pArgTo->GetValue();
953 } else if (pArgFrom->GetFound() || pArgTo->GetFound()) {
954 // Only from or to was specified but both are required
956 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
957 m_cmdData.strMiCmd.c_str()));
958 return MIstatus::failure;
961 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
962 m_bValueValid = rValue.IsValid();
964 return MIstatus::success;
966 const MIuint nChildren = rValue.GetNumChildren();
967 m_bHasMore = nTo < nChildren;
968 nTo = std::min(nTo, nChildren);
969 m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
970 for (MIuint i = nFrom; i < nTo; i++) {
971 lldb::SBValue member = rValue.GetChildAtIndex(i);
972 const CMICmnLLDBUtilSBValue utilValue(member);
973 const CMIUtilString strExp = utilValue.GetName();
974 const CMIUtilString name(
975 strExp.empty() ? CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i)
976 : CMIUtilString::Format("%s.%s", rVarObjName.c_str(),
978 const MIuint nChildren = member.GetNumChildren();
979 const CMIUtilString strThreadId(
980 CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
982 // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
984 CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
987 // "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
988 const CMICmnMIValueConst miValueConst(name);
989 const CMICmnMIValueResult miValueResult("name", miValueConst);
990 CMICmnMIValueTuple miValueTuple(miValueResult);
991 const CMICmnMIValueConst miValueConst2(strExp);
992 const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
993 miValueTuple.Add(miValueResult2);
994 const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
995 const CMICmnMIValueConst miValueConst3(strNumChild);
996 const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
997 miValueTuple.Add(miValueResult3);
998 const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
999 const CMICmnMIValueResult miValueResult5("type", miValueConst5);
1000 miValueTuple.Add(miValueResult5);
1001 const CMICmnMIValueConst miValueConst6(strThreadId);
1002 const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
1003 miValueTuple.Add(miValueResult6);
1004 // nChildren == 0 is used to check for simple values
1005 if (eVarInfoFormat ==
1006 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
1008 CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
1010 const CMIUtilString strValue(
1011 CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
1012 member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
1013 const CMICmnMIValueConst miValueConst7(strValue);
1014 const CMICmnMIValueResult miValueResult7("value", miValueConst7);
1015 miValueTuple.Add(miValueResult7);
1017 const CMICmnMIValueConst miValueConst8("0");
1018 const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
1019 miValueTuple.Add(miValueResult8);
1020 const CMICmnMIValueResult miValueResult9("child", miValueTuple);
1021 m_miValueList.Add(miValueResult9);
1024 return MIstatus::success;
1028 // Details: The invoker requires this function. The command prepares a MI Record
1030 // for the work carried out in the Execute().
1031 // Type: Overridden.
1033 // Return: MIstatus::success - Functional succeeded.
1034 // MIstatus::failure - Functional failed.
1037 bool CMICmdCmdVarListChildren::Acknowledge() {
1038 if (m_bValueValid) {
1039 // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
1040 const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
1041 const CMICmnMIValueConst miValueConst(strNumChild);
1042 CMICmnMIValueResult miValueResult("numchild", miValueConst);
1043 if (m_nChildren != 0)
1044 miValueResult.Add("children", m_miValueList);
1045 const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
1046 const CMICmnMIValueConst miValueConst2(strHasMore);
1047 miValueResult.Add("has_more", miValueConst2);
1049 const CMICmnMIResultRecord miRecordResult(
1050 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1052 m_miResultRecord = miRecordResult;
1054 return MIstatus::success;
1057 // MI print "%s^error,msg=\"variable invalid\""
1058 const CMICmnMIValueConst miValueConst("variable invalid");
1059 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1060 const CMICmnMIResultRecord miRecordResult(
1061 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1063 m_miResultRecord = miRecordResult;
1065 return MIstatus::success;
1069 // Details: Required by the CMICmdFactory when registering *this command. The
1071 // calls this function to create an instance of *this command.
1072 // Type: Static method.
1074 // Return: CMICmdBase * - Pointer to a new command.
1077 CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
1078 return new CMICmdCmdVarListChildren();
1083 // Details: CMICmdCmdVarEvaluateExpression constructor.
1089 CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
1090 : m_bValueValid(true), m_constStrArgFormatSpec("-f"),
1091 m_constStrArgName("name") {
1092 // Command factory matches this name with that received from the stdin stream
1093 m_strMiCmd = "var-evaluate-expression";
1095 // Required by the CMICmdFactory when registering *this command
1096 m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
1100 // Details: CMICmdCmdVarEvaluateExpression destructor.
1101 // Type: Overrideable.
1106 CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
1109 // Details: The invoker requires this function. The parses the command line
1111 // arguments to extract values for each of those arguments.
1112 // Type: Overridden.
1114 // Return: MIstatus::success - Functional succeeded.
1115 // MIstatus::failure - Functional failed.
1118 bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
1120 new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false,
1121 CMICmdArgValListBase::eArgValType_String, 1));
1122 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1123 return ParseValidateCmdOptions();
1127 // Details: The invoker requires this function. The command does work in this
1129 // The command is likely to communicate with the LLDB SBDebugger in
1131 // Type: Overridden.
1133 // Return: MIstatus::success - Functional succeeded.
1134 // MIstatus::failure - Functional failed.
1137 bool CMICmdCmdVarEvaluateExpression::Execute() {
1138 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1140 const CMIUtilString &rVarObjName(pArgName->GetValue());
1141 CMICmnLLDBDebugSessionInfoVarObj varObj;
1142 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1143 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1144 m_cmdData.strMiCmd.c_str(),
1145 rVarObjName.c_str()));
1146 return MIstatus::failure;
1149 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1150 m_bValueValid = rValue.IsValid();
1152 return MIstatus::success;
1154 m_varObjName = rVarObjName;
1155 varObj.UpdateValue();
1157 return MIstatus::success;
1161 // Details: The invoker requires this function. The command prepares a MI Record
1163 // for the work carried out in the Execute().
1164 // Type: Overridden.
1166 // Return: MIstatus::success - Functional succeeded.
1167 // MIstatus::failure - Functional failed.
1170 bool CMICmdCmdVarEvaluateExpression::Acknowledge() {
1171 if (m_bValueValid) {
1172 CMICmnLLDBDebugSessionInfoVarObj varObj;
1173 CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
1174 const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
1175 const CMICmnMIValueResult miValueResult("value", miValueConst);
1176 const CMICmnMIResultRecord miRecordResult(
1177 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1179 m_miResultRecord = miRecordResult;
1180 return MIstatus::success;
1183 const CMICmnMIValueConst miValueConst("variable invalid");
1184 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1185 const CMICmnMIResultRecord miRecordResult(
1186 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1188 m_miResultRecord = miRecordResult;
1189 return MIstatus::success;
1193 // Details: Required by the CMICmdFactory when registering *this command. The
1195 // calls this function to create an instance of *this command.
1196 // Type: Static method.
1198 // Return: CMICmdBase * - Pointer to a new command.
1201 CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
1202 return new CMICmdCmdVarEvaluateExpression();
1207 // Details: CMICmdCmdVarInfoPathExpression constructor.
1213 CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
1214 : m_bValueValid(true), m_constStrArgName("name") {
1215 // Command factory matches this name with that received from the stdin stream
1216 m_strMiCmd = "var-info-path-expression";
1218 // Required by the CMICmdFactory when registering *this command
1219 m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
1223 // Details: CMICmdCmdVarInfoPathExpression destructor.
1224 // Type: Overrideable.
1229 CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
1232 // Details: The invoker requires this function. The parses the command line
1234 // arguments to extract values for each of those arguments.
1235 // Type: Overridden.
1237 // Return: MIstatus::success - Functional succeeded.
1238 // MIstatus::failure - Functional failed.
1241 bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
1242 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1243 return ParseValidateCmdOptions();
1247 // Details: The invoker requires this function. The command does work in this
1249 // The command is likely to communicate with the LLDB SBDebugger in
1251 // Type: Overridden.
1253 // Return: MIstatus::success - Functional succeeded.
1254 // MIstatus::failure - Functional failed.
1257 bool CMICmdCmdVarInfoPathExpression::Execute() {
1258 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1260 const CMIUtilString &rVarObjName(pArgName->GetValue());
1261 CMICmnLLDBDebugSessionInfoVarObj varObj;
1262 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1263 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1264 m_cmdData.strMiCmd.c_str(),
1265 rVarObjName.c_str()));
1266 return MIstatus::failure;
1269 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
1270 m_bValueValid = rValue.IsValid();
1272 return MIstatus::success;
1274 lldb::SBStream stream;
1275 if (!rValue.GetExpressionPath(stream, true)) {
1276 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH),
1277 m_cmdData.strMiCmd.c_str(),
1278 rVarObjName.c_str()));
1279 return MIstatus::failure;
1282 const char *pPathExpression = stream.GetData();
1283 if (pPathExpression == nullptr) {
1284 // Build expression from what we do know
1285 m_strPathExpression = varObj.GetNameReal();
1286 return MIstatus::success;
1289 // Has LLDB returned a var signature of it's own
1290 if (pPathExpression[0] != '$') {
1291 m_strPathExpression = pPathExpression;
1292 return MIstatus::success;
1295 // Build expression from what we do know
1296 const CMIUtilString &rVarParentName(varObj.GetVarParentName());
1297 if (rVarParentName.empty()) {
1298 m_strPathExpression = varObj.GetNameReal();
1300 CMICmnLLDBDebugSessionInfoVarObj varObjParent;
1301 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
1303 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1304 m_cmdData.strMiCmd.c_str(),
1305 rVarParentName.c_str()));
1306 return MIstatus::failure;
1308 m_strPathExpression =
1309 CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
1310 varObj.GetNameReal().c_str());
1313 return MIstatus::success;
1317 // Details: The invoker requires this function. The command prepares a MI Record
1319 // for the work carried out in the Execute().
1320 // Type: Overridden.
1322 // Return: MIstatus::success - Functional succeeded.
1323 // MIstatus::failure - Functional failed.
1326 bool CMICmdCmdVarInfoPathExpression::Acknowledge() {
1327 if (m_bValueValid) {
1328 const CMICmnMIValueConst miValueConst(m_strPathExpression);
1329 const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
1330 const CMICmnMIResultRecord miRecordResult(
1331 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1333 m_miResultRecord = miRecordResult;
1334 return MIstatus::success;
1337 const CMICmnMIValueConst miValueConst("variable invalid");
1338 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1339 const CMICmnMIResultRecord miRecordResult(
1340 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1342 m_miResultRecord = miRecordResult;
1344 return MIstatus::success;
1348 // Details: Required by the CMICmdFactory when registering *this command. The
1350 // calls this function to create an instance of *this command.
1351 // Type: Static method.
1353 // Return: CMICmdBase * - Pointer to a new command.
1356 CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
1357 return new CMICmdCmdVarInfoPathExpression();
1362 // Details: CMICmdCmdVarShowAttributes constructor.
1368 CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
1369 : m_constStrArgName("name") {
1370 // Command factory matches this name with that received from the stdin stream
1371 m_strMiCmd = "var-show-attributes";
1373 // Required by the CMICmdFactory when registering *this command
1374 m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
1378 // Details: CMICmdCmdVarShowAttributes destructor.
1379 // Type: Overrideable.
1384 CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
1387 // Details: The invoker requires this function. The parses the command line
1389 // arguments to extract values for each of those arguments.
1390 // Type: Overridden.
1392 // Return: MIstatus::success - Functional succeeded.
1393 // MIstatus::failure - Functional failed.
1396 bool CMICmdCmdVarShowAttributes::ParseArgs() {
1397 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
1398 return ParseValidateCmdOptions();
1402 // Details: The invoker requires this function. The command does work in this
1404 // The command is likely to communicate with the LLDB SBDebugger in
1406 // Type: Overridden.
1408 // Return: MIstatus::success - Functional succeeded.
1409 // MIstatus::failure - Functional failed.
1412 bool CMICmdCmdVarShowAttributes::Execute() {
1413 CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
1415 const CMIUtilString &rVarObjName(pArgName->GetValue());
1416 CMICmnLLDBDebugSessionInfoVarObj varObj;
1417 if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
1418 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
1419 m_cmdData.strMiCmd.c_str(),
1420 rVarObjName.c_str()));
1421 return MIstatus::failure;
1424 return MIstatus::success;
1428 // Details: The invoker requires this function. The command prepares a MI Record
1430 // for the work carried out in the Execute().
1431 // Type: Overridden.
1433 // Return: MIstatus::success - Functional succeeded.
1434 // MIstatus::failure - Functional failed.
1437 bool CMICmdCmdVarShowAttributes::Acknowledge() {
1438 // MI output: "%s^done,status=\"editable\"]"
1439 const CMICmnMIValueConst miValueConst("editable");
1440 const CMICmnMIValueResult miValueResult("status", miValueConst);
1441 const CMICmnMIResultRecord miRecordResult(
1442 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1444 m_miResultRecord = miRecordResult;
1446 return MIstatus::success;
1450 // Details: Required by the CMICmdFactory when registering *this command. The
1452 // calls this function to create an instance of *this command.
1453 // Type: Static method.
1455 // Return: CMICmdBase * - Pointer to a new command.
1458 CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
1459 return new CMICmdCmdVarShowAttributes();