1370b324cSopenharmony_ci// CommandLineParser.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "CommandLineParser.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_cinamespace NCommandLineParser { 8370b324cSopenharmony_ci 9370b324cSopenharmony_cibool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) 10370b324cSopenharmony_ci{ 11370b324cSopenharmony_ci dest1.Empty(); 12370b324cSopenharmony_ci dest2.Empty(); 13370b324cSopenharmony_ci bool quoteMode = false; 14370b324cSopenharmony_ci unsigned i; 15370b324cSopenharmony_ci for (i = 0; i < src.Len(); i++) 16370b324cSopenharmony_ci { 17370b324cSopenharmony_ci wchar_t c = src[i]; 18370b324cSopenharmony_ci if ((c == L' ' || c == L'\t') && !quoteMode) 19370b324cSopenharmony_ci { 20370b324cSopenharmony_ci dest2 = src.Ptr(i + 1); 21370b324cSopenharmony_ci return i != 0; 22370b324cSopenharmony_ci } 23370b324cSopenharmony_ci if (c == L'\"') 24370b324cSopenharmony_ci quoteMode = !quoteMode; 25370b324cSopenharmony_ci else 26370b324cSopenharmony_ci dest1 += c; 27370b324cSopenharmony_ci } 28370b324cSopenharmony_ci return i != 0; 29370b324cSopenharmony_ci} 30370b324cSopenharmony_ci 31370b324cSopenharmony_civoid SplitCommandLine(const UString &s, UStringVector &parts) 32370b324cSopenharmony_ci{ 33370b324cSopenharmony_ci UString sTemp (s); 34370b324cSopenharmony_ci sTemp.Trim(); 35370b324cSopenharmony_ci parts.Clear(); 36370b324cSopenharmony_ci for (;;) 37370b324cSopenharmony_ci { 38370b324cSopenharmony_ci UString s1, s2; 39370b324cSopenharmony_ci if (SplitCommandLine(sTemp, s1, s2)) 40370b324cSopenharmony_ci parts.Add(s1); 41370b324cSopenharmony_ci if (s2.IsEmpty()) 42370b324cSopenharmony_ci break; 43370b324cSopenharmony_ci sTemp = s2; 44370b324cSopenharmony_ci } 45370b324cSopenharmony_ci} 46370b324cSopenharmony_ci 47370b324cSopenharmony_ci 48370b324cSopenharmony_cistatic const char * const kStopSwitchParsing = "--"; 49370b324cSopenharmony_ci 50370b324cSopenharmony_cistatic bool inline IsItSwitchChar(wchar_t c) 51370b324cSopenharmony_ci{ 52370b324cSopenharmony_ci return (c == '-'); 53370b324cSopenharmony_ci} 54370b324cSopenharmony_ci 55370b324cSopenharmony_ciCParser::CParser(): 56370b324cSopenharmony_ci _switches(NULL), 57370b324cSopenharmony_ci StopSwitchIndex(-1) 58370b324cSopenharmony_ci{ 59370b324cSopenharmony_ci} 60370b324cSopenharmony_ci 61370b324cSopenharmony_ciCParser::~CParser() 62370b324cSopenharmony_ci{ 63370b324cSopenharmony_ci delete []_switches; 64370b324cSopenharmony_ci} 65370b324cSopenharmony_ci 66370b324cSopenharmony_ci 67370b324cSopenharmony_ci// if (s) contains switch then function updates switch structures 68370b324cSopenharmony_ci// out: true, if (s) is a switch 69370b324cSopenharmony_cibool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches) 70370b324cSopenharmony_ci{ 71370b324cSopenharmony_ci if (s.IsEmpty() || !IsItSwitchChar(s[0])) 72370b324cSopenharmony_ci return false; 73370b324cSopenharmony_ci 74370b324cSopenharmony_ci unsigned pos = 1; 75370b324cSopenharmony_ci unsigned switchIndex = 0; 76370b324cSopenharmony_ci int maxLen = -1; 77370b324cSopenharmony_ci 78370b324cSopenharmony_ci for (unsigned i = 0; i < numSwitches; i++) 79370b324cSopenharmony_ci { 80370b324cSopenharmony_ci const char * const key = switchForms[i].Key; 81370b324cSopenharmony_ci unsigned switchLen = MyStringLen(key); 82370b324cSopenharmony_ci if ((int)switchLen <= maxLen || pos + switchLen > s.Len()) 83370b324cSopenharmony_ci continue; 84370b324cSopenharmony_ci if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key)) 85370b324cSopenharmony_ci { 86370b324cSopenharmony_ci switchIndex = i; 87370b324cSopenharmony_ci maxLen = (int)switchLen; 88370b324cSopenharmony_ci } 89370b324cSopenharmony_ci } 90370b324cSopenharmony_ci 91370b324cSopenharmony_ci if (maxLen < 0) 92370b324cSopenharmony_ci { 93370b324cSopenharmony_ci ErrorMessage = "Unknown switch:"; 94370b324cSopenharmony_ci return false; 95370b324cSopenharmony_ci } 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci pos += (unsigned)maxLen; 98370b324cSopenharmony_ci 99370b324cSopenharmony_ci CSwitchResult &sw = _switches[switchIndex]; 100370b324cSopenharmony_ci const CSwitchForm &form = switchForms[switchIndex]; 101370b324cSopenharmony_ci 102370b324cSopenharmony_ci if (!form.Multi && sw.ThereIs) 103370b324cSopenharmony_ci { 104370b324cSopenharmony_ci ErrorMessage = "Multiple instances for switch:"; 105370b324cSopenharmony_ci return false; 106370b324cSopenharmony_ci } 107370b324cSopenharmony_ci 108370b324cSopenharmony_ci sw.ThereIs = true; 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci const unsigned rem = s.Len() - pos; 111370b324cSopenharmony_ci if (rem < form.MinLen) 112370b324cSopenharmony_ci { 113370b324cSopenharmony_ci ErrorMessage = "Too short switch:"; 114370b324cSopenharmony_ci return false; 115370b324cSopenharmony_ci } 116370b324cSopenharmony_ci 117370b324cSopenharmony_ci sw.WithMinus = false; 118370b324cSopenharmony_ci sw.PostCharIndex = -1; 119370b324cSopenharmony_ci 120370b324cSopenharmony_ci switch (form.Type) 121370b324cSopenharmony_ci { 122370b324cSopenharmony_ci case NSwitchType::kMinus: 123370b324cSopenharmony_ci if (rem == 1) 124370b324cSopenharmony_ci { 125370b324cSopenharmony_ci sw.WithMinus = (s[pos] == '-'); 126370b324cSopenharmony_ci if (sw.WithMinus) 127370b324cSopenharmony_ci return true; 128370b324cSopenharmony_ci ErrorMessage = "Incorrect switch postfix:"; 129370b324cSopenharmony_ci return false; 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci break; 132370b324cSopenharmony_ci 133370b324cSopenharmony_ci case NSwitchType::kChar: 134370b324cSopenharmony_ci if (rem == 1) 135370b324cSopenharmony_ci { 136370b324cSopenharmony_ci wchar_t c = s[pos]; 137370b324cSopenharmony_ci if (c <= 0x7F) 138370b324cSopenharmony_ci { 139370b324cSopenharmony_ci sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c); 140370b324cSopenharmony_ci if (sw.PostCharIndex >= 0) 141370b324cSopenharmony_ci return true; 142370b324cSopenharmony_ci } 143370b324cSopenharmony_ci ErrorMessage = "Incorrect switch postfix:"; 144370b324cSopenharmony_ci return false; 145370b324cSopenharmony_ci } 146370b324cSopenharmony_ci break; 147370b324cSopenharmony_ci 148370b324cSopenharmony_ci case NSwitchType::kString: 149370b324cSopenharmony_ci { 150370b324cSopenharmony_ci sw.PostStrings.Add(s.Ptr(pos)); 151370b324cSopenharmony_ci return true; 152370b324cSopenharmony_ci } 153370b324cSopenharmony_ci } 154370b324cSopenharmony_ci 155370b324cSopenharmony_ci if (pos != s.Len()) 156370b324cSopenharmony_ci { 157370b324cSopenharmony_ci ErrorMessage = "Too long switch:"; 158370b324cSopenharmony_ci return false; 159370b324cSopenharmony_ci } 160370b324cSopenharmony_ci return true; 161370b324cSopenharmony_ci} 162370b324cSopenharmony_ci 163370b324cSopenharmony_ci 164370b324cSopenharmony_cibool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings) 165370b324cSopenharmony_ci{ 166370b324cSopenharmony_ci StopSwitchIndex = -1; 167370b324cSopenharmony_ci ErrorMessage.Empty(); 168370b324cSopenharmony_ci ErrorLine.Empty(); 169370b324cSopenharmony_ci NonSwitchStrings.Clear(); 170370b324cSopenharmony_ci delete []_switches; 171370b324cSopenharmony_ci _switches = NULL; 172370b324cSopenharmony_ci _switches = new CSwitchResult[numSwitches]; 173370b324cSopenharmony_ci 174370b324cSopenharmony_ci FOR_VECTOR (i, commandStrings) 175370b324cSopenharmony_ci { 176370b324cSopenharmony_ci const UString &s = commandStrings[i]; 177370b324cSopenharmony_ci if (StopSwitchIndex < 0) 178370b324cSopenharmony_ci { 179370b324cSopenharmony_ci if (s.IsEqualTo(kStopSwitchParsing)) 180370b324cSopenharmony_ci { 181370b324cSopenharmony_ci StopSwitchIndex = (int)NonSwitchStrings.Size(); 182370b324cSopenharmony_ci continue; 183370b324cSopenharmony_ci } 184370b324cSopenharmony_ci if (!s.IsEmpty() && IsItSwitchChar(s[0])) 185370b324cSopenharmony_ci { 186370b324cSopenharmony_ci if (ParseString(s, switchForms, numSwitches)) 187370b324cSopenharmony_ci continue; 188370b324cSopenharmony_ci ErrorLine = s; 189370b324cSopenharmony_ci return false; 190370b324cSopenharmony_ci } 191370b324cSopenharmony_ci } 192370b324cSopenharmony_ci NonSwitchStrings.Add(s); 193370b324cSopenharmony_ci } 194370b324cSopenharmony_ci return true; 195370b324cSopenharmony_ci} 196370b324cSopenharmony_ci 197370b324cSopenharmony_ci} 198