//++ ------------------------------------------------------------------------------------ // 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: Parse the command's argument options string and try to extract all the words // between quotes then 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::ValidateQuotedText( CMICmdArgContext & vrwArgContext ) { // CODETAG_QUOTEDTEXT_SIMILAR_CODE const CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse(); const MIchar cQuote = '"'; const MIint nPos = strOptions.find( cQuote ); if( nPos == (MIint) std::string::npos ) return ValidateSingleText( vrwArgContext ); // Is one and only quote at end of the string if( nPos == (MIint)(strOptions.length() - 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.find( cQuote, nPos + 1 ); if( nPos2 == (MIint) std::string::npos ) 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". // 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: 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 m_bMandatory ? MIstatus::failure : 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 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 m_bMandatory ? MIstatus::failure : 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: 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 m_bMandatory ? MIstatus::failure : 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: 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. 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 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 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: 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( !vwCmdArgsText.IsEmpty() ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN ), vwCmdArgsText.GetArgsLeftToParse().c_str() ) ); return MIstatus::failure; } if( IsArgsPresentButNotHandledByCmd() ) WarningArgsNotHandledbyCmdLogFile( vStrMiCmd ); 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; } } if( bArgsMissing && bArgsInvalid ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID ), strListMissing.c_str(), strListInvalid.c_str() ) ); return MIstatus::failure; } if( bArgsMissing ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY ), strListMissing.c_str() ) ); return MIstatus::failure; } if( bArgsMissingInfo ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF ), strListMissingInfo.c_str() ) ); return MIstatus::failure; } if( bArgsInvalid ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), strListInvalid.c_str() ) ); return MIstatus::failure; } return MIstatus::success; }