// CommandLineParser.cpp#include"StdAfx.h"#include"CommandLineParser.h"namespaceNCommandLineParser{boolSplitCommandLine(constUString&src,UString&dest1,UString&dest2){dest1.Empty();dest2.Empty();boolquoteMode=false;inti;for(i=0;i<src.Length();i++){wchar_tc=src[i];if(c==L' '&&!quoteMode){dest2=src.Mid(i+1);returni!=0;}if(c==L'\"')quoteMode=!quoteMode;elsedest1+=c;}returni!=0;}voidSplitCommandLine(constUString&s,UStringVector&parts){UStringsTemp=s;sTemp.Trim();parts.Clear();for(;;){UStrings1,s2;if(SplitCommandLine(sTemp,s1,s2))parts.Add(s1);if(s2.IsEmpty())break;sTemp=s2;}}staticconstwchar_tkSwitchID1='-';// static const wchar_t kSwitchID2 = '/';staticconstwchar_tkSwitchMinus='-';staticconstwchar_t*kStopSwitchParsing=L"--";staticboolIsItSwitchChar(wchar_tc){return(c==kSwitchID1/*|| c == kSwitchID2 */);}CParser::CParser(intnumSwitches):_numSwitches(numSwitches){_switches=newCSwitchResult[_numSwitches];}CParser::~CParser(){delete[]_switches;}voidCParser::ParseStrings(constCSwitchForm*switchForms,constUStringVector&commandStrings){intnumCommandStrings=commandStrings.Size();boolstopSwitch=false;for(inti=0;i<numCommandStrings;i++){constUString&s=commandStrings[i];if(stopSwitch)NonSwitchStrings.Add(s);elseif(s==kStopSwitchParsing)stopSwitch=true;elseif(!ParseString(s,switchForms))NonSwitchStrings.Add(s);}}// if string contains switch then function updates switch structures// out: (string is a switch)boolCParser::ParseString(constUString&s,constCSwitchForm*switchForms){intlen=s.Length();if(len==0)returnfalse;intpos=0;if(!IsItSwitchChar(s[pos]))returnfalse;while(pos<len){if(IsItSwitchChar(s[pos]))pos++;constintkNoLen=-1;intmatchedSwitchIndex=0;// GCC WarningintmaxLen=kNoLen;for(intswitchIndex=0;switchIndex<_numSwitches;switchIndex++){intswitchLen=MyStringLen(switchForms[switchIndex].IDString);if(switchLen<=maxLen||pos+switchLen>len)continue;UStringtemp=s+pos;temp=temp.Left(switchLen);if(temp.CompareNoCase(switchForms[switchIndex].IDString)==0)// if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0){matchedSwitchIndex=switchIndex;maxLen=switchLen;}}if(maxLen==kNoLen)throw"maxLen == kNoLen";CSwitchResult&matchedSwitch=_switches[matchedSwitchIndex];constCSwitchForm&switchForm=switchForms[matchedSwitchIndex];if((!switchForm.Multi)&&matchedSwitch.ThereIs)throw"switch must be single";matchedSwitch.ThereIs=true;pos+=maxLen;inttailSize=len-pos;NSwitchType::EEnumtype=switchForm.Type;switch(type){caseNSwitchType::kPostMinus:{if(tailSize==0)matchedSwitch.WithMinus=false;else{matchedSwitch.WithMinus=(s[pos]==kSwitchMinus);if(matchedSwitch.WithMinus)pos++;}break;}caseNSwitchType::kPostChar:{if(tailSize<switchForm.MinLen)throw"switch is not full";UStringset=switchForm.PostCharSet;constintkEmptyCharValue=-1;if(tailSize==0)matchedSwitch.PostCharIndex=kEmptyCharValue;else{intindex=set.Find(s[pos]);if(index<0)matchedSwitch.PostCharIndex=kEmptyCharValue;else{matchedSwitch.PostCharIndex=index;pos++;}}break;}caseNSwitchType::kLimitedPostString:caseNSwitchType::kUnLimitedPostString:{intminLen=switchForm.MinLen;if(tailSize<minLen)throw"switch is not full";if(type==NSwitchType::kUnLimitedPostString){matchedSwitch.PostStrings.Add(s.Mid(pos));returntrue;}intmaxLen=switchForm.MaxLen;UStringstringSwitch=s.Mid(pos,minLen);pos+=minLen;for(inti=minLen;i<maxLen&&pos<len;i++,pos++){wchar_tc=s[pos];if(IsItSwitchChar(c))break;stringSwitch+=c;}matchedSwitch.PostStrings.Add(stringSwitch);break;}caseNSwitchType::kSimple:break;}}returntrue;}constCSwitchResult&CParser::operator[](size_tindex)const{return_switches[index];}/////////////////////////////////// Command parsing proceduresintParseCommand(intnumCommandForms,constCCommandForm*commandForms,constUString&commandString,UString&postString){for(inti=0;i<numCommandForms;i++){constUStringid=commandForms[i].IDString;if(commandForms[i].PostStringMode){if(commandString.Find(id)==0){postString=commandString.Mid(id.Length());returni;}}elseif(commandString==id){postString.Empty();returni;}}return-1;}}