--- /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] <img1> [<img2 .. imgN>] \n"
+ "imgcheck --e32input [options] (<file> | <directory>) \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();
+ }
+}