diff -r 000000000000 -r 044383f39525 imgtools/imgcheck/src/cmdlinehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imgcheck/src/cmdlinehandler.cpp Tue Oct 27 16:36:35 2009 +0000 @@ -0,0 +1,786 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Commandline handler for imgcheck Tool, responsible to parse the +* commandline options and preserve the data for later use +* +*/ + + +/** + @file + @internalComponent + @released +*/ + +#include "cmdlinehandler.h" + +/** +Constructor initializes the iOptionMap with short and long option names as key and +the value pair says whether the respective option can have value or not. + +@internalComponent +@released +*/ +CmdLineHandler::CmdLineHandler() +:iDebuggableFlagVal(false),iXmlFileName(GXmlFileName), iNoImage(true), iCommmandFlag(0), iValidations(0), iSuppressions(0) +{ + iOptionMap[KLongHelpOption] = ENone; + iOptionMap[KLongAllOption] = ENone; + iOptionMap[KLongXmlOption] = ENone; + iOptionMap[KLongOutputOption] = ESingle; //option can have only 1 value + iOptionMap[KLongQuietOption] = ENone; + iOptionMap[KLongVerboseOption] = ENone; + iOptionMap[KLongSuppressOption]= EMultiple; //This value should be updated, while introducing new validations + iOptionMap[KLongVidValOption]= EMultiple; + iOptionMap[KShortHelpOption] = ENone; + iOptionMap[KShortAllOption] = ENone; + iOptionMap[KShortXmlOption] = ENone; + iOptionMap[KShortOutputOption] = ESingle; //option can have only 1 value + iOptionMap[KShortQuietOption] = ENone; + iOptionMap[KShortVerboseOption] = ENone; + iOptionMap[KShortSuppressOption] = EMultiple; + iOptionMap[KShortNoCheck] = ENone; + iOptionMap[KLongSidAllOption] = ENone; + iOptionMap[KLongEnableDepCheck] = ENone; + iOptionMap[KLongEnableSidCheck] = ENone; + iOptionMap[KLongEnableVidCheck] = ENone; + iOptionMap[KLongEnableDbgFlagCheck] = EOptional; + iOptionMap[KLongE32InputOption] = ENone; + iOptionMap[KLongNoCheck] = ENone; + iSuppressVal[KSuppressDependency] = EDep; + iSuppressVal[KSuppressSid] = ESid; + iSuppressVal[KSuppressVid] = EVid; + + Version(); + Usage(); +} + +/** +Destructor. + +@internalComponent +@released +*/ +CmdLineHandler::~CmdLineHandler() +{ + iOptionMap.clear(); + iImageNameList.clear(); + iSuppressVal.clear(); + iVidValList.clear(); +} + +/** +Function to parse the command line options. +Responsible to +1. Parse the input values. +2. Print the usage note. +3. Identify the valdations to be carried out. +4. Type of report needs to be generated. + +@internalComponent +@released + +@param aArgc - argument count +@param aArgv[] - argument values +*/ +ReturnType CmdLineHandler::ProcessCommandLine(unsigned int aArgc, char* aArgv[]) +{ + if(aArgc < 2) + { + std::cout << PrintVersion().c_str() << std::endl; + std::cout << PrintUsage().c_str() << std::endl; + return EQuit; + } + ArgumentList argumentList(&aArgv[0], aArgv + aArgc); + int argCount = argumentList.size(); + + iInputCommand = KToolName; + + for( int i = 1; i < argCount; i++ ) //Skip tool name + { + String name = argumentList.at(i); + iInputCommand += " "; + iInputCommand += name; + int longOptionFlag = 0; + if(IsOption(name, longOptionFlag)) + { + String optionName; + bool optionValue = false; + StringList optionValueList; + ParseOption(name, optionName, optionValueList, optionValue); + char shortOption = KNull; + if(Validate(ReaderUtil::ToLower(optionName), optionValue, optionValueList.size())) + { + if(longOptionFlag) + { + shortOption = optionName.at(2); + } + else + { + shortOption = optionName.at(1); + } + } + + switch(shortOption) + { + case 'q': + iCommmandFlag |= QuietMode; + break; + case 'a': + iCommmandFlag |= KAll; + break; + case 'x': + iCommmandFlag |= KXmlReport; + break; + case 'o': + iXmlFileName.assign(optionValueList.front()); + NormaliseName(); + break; + case 's': + if((optionName == KShortSuppressOption) || (optionName == KLongSuppressOption)) + { + String value; + while(optionValueList.size() > 0) + { + value = optionValueList.front(); + if(iSuppressVal[value]) + { + if(iValidations > 0) //Is any check enabled? + { + if(iValidations & iSuppressVal[value]) + { + iValidations ^= iSuppressVal[value]; //Consider only 3 LSB's + } + } + else //Is this valid value? + { + iSuppressions |= iSuppressVal[value]; + } + } + else + { + throw ExceptionReporter(UNKNOWNSUPPRESSVAL,(char*)(optionValueList.front().c_str())); + } + optionValueList.pop_front(); + } + } + else if(optionName == KLongEnableSidCheck) + { + iValidations |= KMarkEnable; + iValidations |= ESid; + } + else if(optionName == KLongSidAllOption) + { + iCommmandFlag |= KSidAll; + } + break; + case 'd': + if(optionName == KLongEnableDbgFlagCheck) + { + iValidations |= KMarkEnable; + iValidations |= EDbg; + if(optionValueList.size() > 0) + { + if(optionValueList.front() == String("true")) + { + iDebuggableFlagVal = true; + } + else if (optionValueList.front() == String("false")) + { + iDebuggableFlagVal = false; + } + else + { + throw ExceptionReporter(UNKNOWNDBGVALUE); + } + } + } + else if (optionName == KLongEnableDepCheck) + { + iValidations |= KMarkEnable; + iValidations |= EDep; + } + break; + + case 'e': + if (optionName == KLongE32InputOption) + { + iCommmandFlag |= KE32Input; + } + break; + + case 'v': + if(optionName == KLongVidValOption) + { + StringListToUnIntList(optionValueList, iVidValList); + } + else if(optionName == KLongEnableVidCheck) + { + iValidations |= KMarkEnable; + iValidations |= EVid; + } + else + { + iCommmandFlag |= KVerbose; + /**Initialize ExceptionImplementation class with verbose mode flag + to print all status information to standard output*/ + ExceptionImplementation::Instance(iCommmandFlag); + } + break; + case 'n': + iCommmandFlag |= KNoCheck; + break; + case 'h': + std::cout << PrintVersion().c_str() << std::endl; + std::cout << PrintUsage().c_str() << std::endl; + return EQuit; //Don't proceed further + } + } + else + { + if(!AlreadyReceived(name)) + { + iImageNameList.push_back(name); + } + else + { + ExceptionReporter(IMAGENAMEALREADYRECEIVED, (char*)name.c_str()).Report(); + } + + iNoImage = false; + } + } //While loop ends here + if((iCommmandFlag || iValidations || iSuppressions) && iNoImage) + { + PrintVersion(); + PrintUsage(); + } + //Always log the version information into log file + ExceptionImplementation::Instance(iCommmandFlag)->Log(iVersion); + ValidateArguments(); + ValidateE32NoCheckArguments(); + if(iCommmandFlag & KE32Input) + { + ValidateImageNameList(); + } + return ESuccess; +} + +/** +Function identify whether the passed string is an option or not. + +@internalComponent +@released + +@param aName - a string received as part of command line +@param aLongOptionFlag - this flag is set if the option is long else +it is assumed as short option. + +@return - returns true or false +*/ +bool CmdLineHandler::IsOption(const String& aName, int& aLongOptionFlag) +{ + unsigned int prefixCount = 0; + while(aName.at(prefixCount) == KShortOptionPrefix) + { + if(aName.length() == ++prefixCount) + { + throw ExceptionReporter(UNKNOWNOPTION, (char*)aName.c_str()); + } + } + + switch(prefixCount) + { + case 0: //argument can be an image + return false; + case 1: // '-' + return true; + case 2: // '--' + aLongOptionFlag = 1; + return true; + default: + throw ExceptionReporter(UNKNOWNPREFIX, (char*)aName.c_str()); + } +} + +/** +Function to do syntax validation on the received option. +1. Identifies whether the received option is valid or not. +2. Identifies whether the option can have vaue or not. +3. Throws an error if no value received for an option which should have value. +4. Throws an error if more number of values received. +5. Throws an error if an unwanted value received. +6. Throws an error if the option is not a valid one. + +@internalComponent +@released + +@param aOption - a string received as part of command line. +@param aOptionValue - Whether option value received or not. +@param aNoOfVal - Number of values received for this option. + +@return - returns true if it is a valid option +*/ +bool CmdLineHandler::Validate(const String& aOption, bool aOptionValue, unsigned int aNoOfVal) +{ + if(iOptionMap.find(aOption) != iOptionMap.end()) + { + if(iOptionMap[aOption]) //Option can have value? + { + if((aNoOfVal == ENone) && (iOptionMap[aOption] != EOptional)) //No values received? + { + throw ExceptionReporter(VALUEEXPECTED, (char*)aOption.c_str()); + } + + if((iOptionMap[aOption] == ESingle) && (ESingle < aNoOfVal)) //Received values are more than expected + { + throw ExceptionReporter(UNEXPECTEDNUMBEROFVALUE,(char*)aOption.c_str()); + } + } + else + { + if(aOptionValue) //Is option value received? Any character after the option considered as value. + { + throw ExceptionReporter(VALUENOTEXPECTED, (char*)aOption.c_str()); + } + } + return true; + } + throw ExceptionReporter(UNKNOWNOPTION, (char*)aOption.c_str()); +} + +/** +Function to split the option name and option values. +1. Ignore's the '=' symbol which is following the option. But this is an error, if that +option does not expecting any value. +2. Parses the value received with options. + +@internalComponent +@released + +@param aFullName - Option with its value +@param aOptionName - Option name put into this parameter +@param aOptionValues - Option values put into this parameter +@param aOptionValue - Set this flag if any value received with the option. +*/ +void CmdLineHandler::ParseOption(const String& aFullName, String& aOptionName, StringList& aOptionValues, bool& aOptionValue) +{ + unsigned int optionEndLocation = aFullName.find("="); + if(optionEndLocation != String::npos) + { + aOptionValue = true; + aOptionName = aFullName.substr(0, optionEndLocation++); + if(aFullName.length() == optionEndLocation) + { + throw ExceptionReporter(VALUEEXPECTED, (char*)aOptionName.c_str()); + } + String sub = aFullName.substr(optionEndLocation); + char* optionValues = (char*)sub.c_str(); + //Get all the values; use (,) as delimiter + char* value = strtok(optionValues,","); + while(value != KNull) + { + String str(value); + aOptionValues.push_back(ReaderUtil::ToLower(str)); + value = strtok(KNull,","); + } + return; + } + aOptionName = aFullName; +} + +/** +Function to initialize the usage. + +@internalComponent +@released +*/ +void CmdLineHandler::Usage(void) +{ + iUsage.assign("imgcheck [options] [] \n" + "imgcheck --e32input [options] ( | ) \n" + "\n" + "options: \n" + " -a, --all, Report all executable's status\n" + " -q, --quiet, Command line display off\n" + " -x, --xml, Generate XML report\n" + " -o=xxx, --output=xxx Override default XML file name\n" + " -v, --verbose, Verbose mode output\n" + " -h, --help, Display this message\n" + " -s=val1[,val2][...], --suppress=val1[,val2][...] \n" + " Suppress one or more check,\n" + " Possible values are dep, sid and vid\n" + " --vidlist=val1[,val2][...] \n" + " One or more VID value(s) \n" + " --dep Enable dependency check\n" + " --vid Enable VID check\n" + " --sid Enable SID check, only EXEs are considered by default\n" + " --sidall Include DLL also into SID check\n" + " --dbg[=val] Enable Debug flag check,\n" + " Optionally over ride the default value 'false'\n" + " --e32input Switches the tool to filesystem mode\n" + " -n, --nocheck Don't report any check(s) status\n"); +} + +/** +Function to return the usage. + +@internalComponent +@released +*/ +const String& CmdLineHandler::PrintUsage(void) const +{ + return iUsage; +} + +/** +Function to prepare the version information. + +@internalComponent +@released +*/ +void CmdLineHandler::Version(void) +{ + iVersion.append(gToolDesc); + iVersion.append(gMajorVersion); + iVersion.append(gMinorVersion); + iVersion.append(gMaintenanceVersion); + iVersion.append(gCopyright); +} + +/** +Function to return the version information. + +@internalComponent +@released +*/ +const String& CmdLineHandler::PrintVersion(void) const +{ + return iVersion; +} + +/** +Function to return the image name one by one. + +@internalComponent +@released + +@return - returns image name +*/ +String CmdLineHandler::NextImageName(void) +{ + String imageName = iImageNameList.front(); + iImageNameList.pop_front(); + return imageName; +} + +/** +Function to return the iCommmandFlag. + +@internalComponent +@released + +@return - returns iCommmandFlag value. +*/ +const unsigned int CmdLineHandler::ReportFlag(void) const +{ + return iCommmandFlag; +} + +/** +Function to return the iXmlFileName. + +@internalComponent +@released + +@return - returns iXmlFileName value. +*/ +const String& CmdLineHandler::XmlReportName(void) const +{ + return iXmlFileName; +} + + +/** +Function to append the XML extension to the received XML name. + +@internalComponent +@released +*/ +void CmdLineHandler::NormaliseName(void) +{ + if (iXmlFileName.find(KXmlExtension) == String::npos) + { + iXmlFileName.append(KXmlExtension); + } +} + +/** +Function to validate the arguements to ensure that the tool is invoked with proper +arguments. + +@internalComponent +@released +*/ +void CmdLineHandler::ValidateArguments(void) const +{ + unsigned int validations = EnabledValidations(); + validations = (validations & KMarkEnable) ? iValidations ^ KMarkEnable:validations; //disable MSB + + if( iCommmandFlag & QuietMode && !(iCommmandFlag & KXmlReport)) + { + throw ExceptionReporter(QUIETMODESELECTED); + } + + if(!(iCommmandFlag & KXmlReport) && (iXmlFileName != GXmlFileName)) + { + ExceptionReporter(XMLOPTION).Report(); + } + + if((iVidValList.size() > 0) && (validations & EVid) == 0) + { + ExceptionReporter(SUPPRESSCOMBINEDWITHVIDVAL).Report(); + } + + if((iCommmandFlag & KSidAll) && ((validations & ESid)==0)) + { + ExceptionReporter(SIDALLCOMBINEDWITHSID).Report(); + } + + if( validations == ENone) + { + throw ExceptionReporter(ALLCHECKSSUPPRESSED); + } + + if(iNoImage) + { + throw ExceptionReporter(NOIMAGE); + } +} + +/** +Function to return number of images received through command line. + +@internalComponent +@released +*/ +unsigned int CmdLineHandler::NoOfImages(void) const +{ + return iImageNameList.size(); +} + +/** +Function to return Validations needs to be performed. +1. If any validation is enabled, then only enabled validations are carried. +2. If any validation is suppressed, then all validations are carried execept the suppressed ones. + +@internalComponent +@released + +@return - returns the enabled Validations +*/ +const unsigned int CmdLineHandler::EnabledValidations(void) const +{ + if(iValidations > 0) + { + return iValidations; + } + return (iSuppressions ^ EAllValidation); //Enable unsuppressed options +} + +/** +Function to convert strings to integers. +1. If any validation is enabled, then only enabled validations are carried. +2. If any validation is suppressed, then all validations are carried execept the suppressed ones. +3. Throws an error if the value is not a decimal or hexadecimal one. + +@internalComponent +@released + +@param aStrList - List VID values received at command line +@param aUnIntList - Received values are validated and put into this container. +*/ +void CmdLineHandler::StringListToUnIntList(StringList& aStrList, UnIntList& aUnIntList) +{ + String tempString; + Long64 intValue = 0; + while(aStrList.size() > 0) + { + tempString = aStrList.front(); + if(tempString.length() >= 2) //Hex number should start with '0x' + { + //is this an Hexadecimal number? + if((tempString.at(0) == '0') && (tempString.at(1) == 'x')) + { + tempString = tempString.substr(2); + unsigned int location = 0; + if(!tempString.empty()) + { + while(location < tempString.length()) //Ignore proceeding zeros. + { + if(tempString.at(location) == '0') + { + location++; + continue; + } + break; + } + } + else + { + throw ExceptionReporter(INVALIDVIDVALUE,(char*)aStrList.front().c_str()); + } + tempString = tempString.substr(location); + if(tempString.empty() && location != 0) + { + tempString = '0'; + } + unsigned int strLength = tempString.length(); + if(strLength <= KHexEightByte && strLength > 0) + { + if(tempString.find_first_not_of(KHexNumber) == String::npos) + { + aUnIntList.push_back(ReaderUtil::HexStrToInt(tempString)); + aStrList.pop_front(); + continue; + } + } + else + { + throw ExceptionReporter(DATAOVERFLOW,(char*)tempString.c_str()); + } + } + } + //is this an Decimal number? + if(tempString.find_first_not_of(KDecNumber) == String::npos) + { + intValue = ReaderUtil::DecStrToInt(tempString); + if(intValue <= KDecHighValue) + { + aUnIntList.push_back(intValue); + } + else + { + throw ExceptionReporter(DATAOVERFLOW,(char*)tempString.c_str()); + } + } + else + { + throw ExceptionReporter(INVALIDVIDVALUE,(char*)tempString.c_str()); + } + aStrList.pop_front(); + } +} + + + +/** +Function to return vid value list. + +@internalComponent +@released + +@return - returns vid value list. +*/ +UnIntList& CmdLineHandler::VidValueList() +{ + return iVidValList; +} + +/** +Function to return input command string. + +@internalComponent +@released + +@return - returns iInputCommand. +*/ +const String& CmdLineHandler::Command() const +{ + return iInputCommand; +} + +/** +Function identifies whether the image is already received or not. + +@internalComponent +@released + +@return - returns true if the image is already received. + - returns false if the image is not received already. +*/ +bool CmdLineHandler::AlreadyReceived(String& aName) +{ + StringList::iterator nameBegin = iImageNameList.begin(); + StringList::iterator nameEnd = iImageNameList.end(); + while(nameBegin != nameEnd) + { + if(aName == *nameBegin) + { + return true; + } + ++nameBegin; + } + return false; +} + +/** +Function to return debug flag value. + +@internalComponent +@released + +@return - returns iDebuggableFlagVal. +*/ +bool CmdLineHandler::DebuggableFlagVal() +{ + return iDebuggableFlagVal; +} + +/** +Function to validate the e32 input. + +@internalComponent +@released + +*/ +void CmdLineHandler::ValidateImageNameList(void) +{ + if(iImageNameList.size() > 1) + { + throw ExceptionReporter(ONLYSINGLEDIRECTORYEXPECTED); + } +} + + +/** +Function to validate the e32 and no check option arguments. + +@internalComponent +@released + +*/ +void CmdLineHandler::ValidateE32NoCheckArguments(void) +{ + if((iCommmandFlag & KE32Input) && !iValidations) + { + throw ExceptionReporter(NOVALIDATIONSENABLED); + } + + if((iCommmandFlag & KE32Input) && (iValidations & (EDep | ESid))) + { + ExceptionReporter(INCORRECTVALUES).Report(); + } +}