| //===-- MICmdCmdGdbSet.cpp --------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // Overview: CMICmdCmdGdbSet implementation. |
| |
| // 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}, |
| {"print", &CMICmdCmdGdbSet::OptionFnPrint}, |
| // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, // Example code if need to implement GDB set other options |
| {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix}, |
| {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath}, |
| {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}}; |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdGdbSet constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdGdbSet::CMICmdCmdGdbSet() |
| : 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() |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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() |
| { |
| m_setCmdArgs.Add( |
| new CMICmdArgValListOfN(m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringAnything)); |
| return ParseValidateCmdOptions(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command is executed 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() |
| { |
| CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption); |
| const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions()); |
| |
| // Get the gdb-set option to carry out. This option will be used as an action |
| // which should be done. Further arguments will be used as parameters for it. |
| 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() method. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbSet::Acknowledge() |
| { |
| // Print error if option isn't recognized: |
| // ^error,msg="The request '%s' was not recognized, not implemented" |
| 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; |
| } |
| |
| // ^done,value="%s" |
| if (m_bGdbOptionFnSuccessful) |
| { |
| const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| // Print error if request failed: |
| // ^error,msg="The request '%s' failed. |
| 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() |
| { |
| 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 'target-async' to prepare |
| // and send back information asked for. |
| // Type: Method. |
| // Args: vrWords - (R) List of additional parameters used by this option. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbSet::OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords) |
| { |
| bool bAsyncMode = false; |
| bool bOk = true; |
| |
| if (vrWords.size() > 1) |
| // Too many arguments. |
| bOk = false; |
| else if (vrWords.size() == 0) |
| // If no arguments, default is "on". |
| bAsyncMode = true; |
| else if (CMIUtilString::Compare(vrWords[0], "on")) |
| bAsyncMode = true; |
| else if (CMIUtilString::Compare(vrWords[0], "off")) |
| bAsyncMode = false; |
| else |
| // Unrecognized argument. |
| bOk = false; |
| |
| if (!bOk) |
| { |
| // Report error. |
| m_bGbbOptionFnHasError = true; |
| m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC); |
| return MIstatus::failure; |
| } |
| |
| // Turn async mode on/off. |
| CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); |
| rSessionInfo.GetDebugger().SetAsync(bAsyncMode); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB set option 'print-char-array-as-string' to |
| // prepare and send back information asked for. |
| // Type: Method. |
| // Args: vrWords - (R) List of additional parameters used by this option. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) |
| { |
| const bool bAllArgs(vrWords.size() == 2); |
| const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") || CMIUtilString::Compare(vrWords[1], "1"))); |
| const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") || CMIUtilString::Compare(vrWords[1], "0"))); |
| if (!bAllArgs || (!bArgOn && !bArgOff)) |
| { |
| m_bGbbOptionFnHasError = true; |
| m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS); |
| return MIstatus::failure; |
| } |
| |
| const CMIUtilString strOption(vrWords[0]); |
| CMIUtilString strOptionKey; |
| if (CMIUtilString::Compare(strOption, "char-array-as-string")) |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString; |
| else if (CMIUtilString::Compare(strOption, "expand-aggregates")) |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates; |
| else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames; |
| else |
| { |
| m_bGbbOptionFnHasError = true; |
| m_strGdbOptionFnError = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str()); |
| return MIstatus::failure; |
| } |
| |
| const bool bOptionValue(bArgOn); |
| if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey, bOptionValue)) |
| { |
| m_bGbbOptionFnHasError = false; |
| SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), strOptionKey.c_str())); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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 'output-radix' 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::OptionFnOutputRadix(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 &rStrValOutputRadix(vrWords[0]); |
| |
| CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid; |
| MIint64 radix; |
| if (rStrValOutputRadix.ExtractNumber(radix)) |
| { |
| switch (radix) |
| { |
| case 8: |
| format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal; |
| break; |
| case 10: |
| format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural; |
| break; |
| case 16: |
| format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex; |
| break; |
| default: |
| format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid; |
| break; |
| } |
| } |
| if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) |
| { |
| m_bGbbOptionFnHasError = false; |
| SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), "Output Radix")); |
| return MIstatus::failure; |
| } |
| CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB set option to prepare and send back the |
| // requested information. |
| // 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 function to do nothing. |
| // This allows the search for gdb-set options to always succeed when the option is not |
| // found (implemented). |
| |
| return MIstatus::success; |
| } |