CommandLineParser.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // CommandLineParser.cpp
  2. #include "StdAfx.h"
  3. #include "CommandLineParser.h"
  4. namespace NCommandLineParser {
  5. void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
  6. {
  7. dest1.Empty();
  8. dest2.Empty();
  9. bool quoteMode = false;
  10. int i;
  11. for (i = 0; i < src.Length(); i++)
  12. {
  13. wchar_t c = src[i];
  14. if (c == L'\"')
  15. quoteMode = !quoteMode;
  16. else if (c == L' ' && !quoteMode)
  17. {
  18. i++;
  19. break;
  20. }
  21. else
  22. dest1 += c;
  23. }
  24. dest2 = src.Mid(i);
  25. }
  26. void SplitCommandLine(const UString &s, UStringVector &parts)
  27. {
  28. UString sTemp = s;
  29. sTemp.Trim();
  30. parts.Clear();
  31. for (;;)
  32. {
  33. UString s1, s2;
  34. SplitCommandLine(sTemp, s1, s2);
  35. // s1.Trim();
  36. // s2.Trim();
  37. if (!s1.IsEmpty())
  38. parts.Add(s1);
  39. if (s2.IsEmpty())
  40. break;
  41. sTemp = s2;
  42. }
  43. }
  44. static const wchar_t kSwitchID1 = '-';
  45. // static const wchar_t kSwitchID2 = '/';
  46. static const wchar_t kSwitchMinus = '-';
  47. static const wchar_t *kStopSwitchParsing = L"--";
  48. static bool IsItSwitchChar(wchar_t c)
  49. {
  50. return (c == kSwitchID1 /*|| c == kSwitchID2 */);
  51. }
  52. CParser::CParser(int numSwitches):
  53. _numSwitches(numSwitches)
  54. {
  55. _switches = new CSwitchResult[_numSwitches];
  56. }
  57. CParser::~CParser()
  58. {
  59. delete []_switches;
  60. }
  61. void CParser::ParseStrings(const CSwitchForm *switchForms,
  62. const UStringVector &commandStrings)
  63. {
  64. int numCommandStrings = commandStrings.Size();
  65. bool stopSwitch = false;
  66. for (int i = 0; i < numCommandStrings; i++)
  67. {
  68. const UString &s = commandStrings[i];
  69. if (stopSwitch)
  70. NonSwitchStrings.Add(s);
  71. else
  72. if (s == kStopSwitchParsing)
  73. stopSwitch = true;
  74. else
  75. if (!ParseString(s, switchForms))
  76. NonSwitchStrings.Add(s);
  77. }
  78. }
  79. // if string contains switch then function updates switch structures
  80. // out: (string is a switch)
  81. bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
  82. {
  83. int len = s.Length();
  84. if (len == 0)
  85. return false;
  86. int pos = 0;
  87. if (!IsItSwitchChar(s[pos]))
  88. return false;
  89. while(pos < len)
  90. {
  91. if (IsItSwitchChar(s[pos]))
  92. pos++;
  93. const int kNoLen = -1;
  94. int matchedSwitchIndex = 0; // GCC Warning
  95. int maxLen = kNoLen;
  96. for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
  97. {
  98. int switchLen = MyStringLen(switchForms[switchIndex].IDString);
  99. if (switchLen <= maxLen || pos + switchLen > len)
  100. continue;
  101. UString temp = s + pos;
  102. temp = temp.Left(switchLen);
  103. if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
  104. // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
  105. {
  106. matchedSwitchIndex = switchIndex;
  107. maxLen = switchLen;
  108. }
  109. }
  110. if (maxLen == kNoLen)
  111. throw "maxLen == kNoLen";
  112. CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
  113. const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
  114. if ((!switchForm.Multi) && matchedSwitch.ThereIs)
  115. throw "switch must be single";
  116. matchedSwitch.ThereIs = true;
  117. pos += maxLen;
  118. int tailSize = len - pos;
  119. NSwitchType::EEnum type = switchForm.Type;
  120. switch(type)
  121. {
  122. case NSwitchType::kPostMinus:
  123. {
  124. if (tailSize == 0)
  125. matchedSwitch.WithMinus = false;
  126. else
  127. {
  128. matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
  129. if (matchedSwitch.WithMinus)
  130. pos++;
  131. }
  132. break;
  133. }
  134. case NSwitchType::kPostChar:
  135. {
  136. if (tailSize < switchForm.MinLen)
  137. throw "switch is not full";
  138. UString set = switchForm.PostCharSet;
  139. const int kEmptyCharValue = -1;
  140. if (tailSize == 0)
  141. matchedSwitch.PostCharIndex = kEmptyCharValue;
  142. else
  143. {
  144. int index = set.Find(s[pos]);
  145. if (index < 0)
  146. matchedSwitch.PostCharIndex = kEmptyCharValue;
  147. else
  148. {
  149. matchedSwitch.PostCharIndex = index;
  150. pos++;
  151. }
  152. }
  153. break;
  154. }
  155. case NSwitchType::kLimitedPostString:
  156. case NSwitchType::kUnLimitedPostString:
  157. {
  158. int minLen = switchForm.MinLen;
  159. if (tailSize < minLen)
  160. throw "switch is not full";
  161. if (type == NSwitchType::kUnLimitedPostString)
  162. {
  163. matchedSwitch.PostStrings.Add(s.Mid(pos));
  164. return true;
  165. }
  166. int maxLen = switchForm.MaxLen;
  167. UString stringSwitch = s.Mid(pos, minLen);
  168. pos += minLen;
  169. for(int i = minLen; i < maxLen && pos < len; i++, pos++)
  170. {
  171. wchar_t c = s[pos];
  172. if (IsItSwitchChar(c))
  173. break;
  174. stringSwitch += c;
  175. }
  176. matchedSwitch.PostStrings.Add(stringSwitch);
  177. break;
  178. }
  179. case NSwitchType::kSimple:
  180. break;
  181. }
  182. }
  183. return true;
  184. }
  185. const CSwitchResult& CParser::operator[](size_t index) const
  186. {
  187. return _switches[index];
  188. }
  189. /////////////////////////////////
  190. // Command parsing procedures
  191. int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
  192. const UString &commandString, UString &postString)
  193. {
  194. for(int i = 0; i < numCommandForms; i++)
  195. {
  196. const UString id = commandForms[i].IDString;
  197. if (commandForms[i].PostStringMode)
  198. {
  199. if(commandString.Find(id) == 0)
  200. {
  201. postString = commandString.Mid(id.Length());
  202. return i;
  203. }
  204. }
  205. else
  206. if (commandString == id)
  207. {
  208. postString.Empty();
  209. return i;
  210. }
  211. }
  212. return -1;
  213. }
  214. }