1 // CommandLineParser.cs
4 using System.Collections;
6 namespace SevenZip.CommandLineParser
17 public class SwitchForm
19 public string IDString;
20 public SwitchType Type;
24 public string PostCharSet;
26 public SwitchForm(string idString, SwitchType type, bool multi,
27 int minLen, int maxLen, string postCharSet)
34 PostCharSet = postCharSet;
36 public SwitchForm(string idString, SwitchType type, bool multi, int minLen):
37 this(idString, type, multi, minLen, 0, "")
40 public SwitchForm(string idString, SwitchType type, bool multi):
41 this(idString, type, multi, 0)
46 public class SwitchResult
49 public bool WithMinus;
50 public ArrayList PostStrings = new ArrayList();
51 public int PostCharIndex;
60 public ArrayList NonSwitchStrings = new ArrayList();
61 SwitchResult[] _switches;
63 public Parser(int numSwitches)
65 _switches = new SwitchResult[numSwitches];
66 for (int i = 0; i < numSwitches; i++)
67 _switches[i] = new SwitchResult();
70 bool ParseString(string srcString, SwitchForm[] switchForms)
72 int len = srcString.Length;
76 if (!IsItSwitchChar(srcString[pos]))
80 if (IsItSwitchChar(srcString[pos]))
82 const int kNoLen = -1;
83 int matchedSwitchIndex = 0;
85 for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
87 int switchLen = switchForms[switchIndex].IDString.Length;
88 if (switchLen <= maxLen || pos + switchLen > len)
90 if (String.Compare(switchForms[switchIndex].IDString, 0,
91 srcString, pos, switchLen, true) == 0)
93 matchedSwitchIndex = switchIndex;
98 throw new Exception("maxLen == kNoLen");
99 SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
100 SwitchForm switchForm = switchForms[matchedSwitchIndex];
101 if ((!switchForm.Multi) && matchedSwitch.ThereIs)
102 throw new Exception("switch must be single");
103 matchedSwitch.ThereIs = true;
105 int tailSize = len - pos;
106 SwitchType type = switchForm.Type;
109 case SwitchType.PostMinus:
112 matchedSwitch.WithMinus = false;
115 matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
116 if (matchedSwitch.WithMinus)
121 case SwitchType.PostChar:
123 if (tailSize < switchForm.MinLen)
124 throw new Exception("switch is not full");
125 string charSet = switchForm.PostCharSet;
126 const int kEmptyCharValue = -1;
128 matchedSwitch.PostCharIndex = kEmptyCharValue;
131 int index = charSet.IndexOf(srcString[pos]);
133 matchedSwitch.PostCharIndex = kEmptyCharValue;
136 matchedSwitch.PostCharIndex = index;
142 case SwitchType.LimitedPostString:
143 case SwitchType.UnLimitedPostString:
145 int minLen = switchForm.MinLen;
146 if (tailSize < minLen)
147 throw new Exception("switch is not full");
148 if (type == SwitchType.UnLimitedPostString)
150 matchedSwitch.PostStrings.Add(srcString.Substring(pos));
153 String stringSwitch = srcString.Substring(pos, minLen);
155 for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
157 char c = srcString[pos];
158 if (IsItSwitchChar(c))
162 matchedSwitch.PostStrings.Add(stringSwitch);
171 public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
173 int numCommandStrings = commandStrings.Length;
174 bool stopSwitch = false;
175 for (int i = 0; i < numCommandStrings; i++)
177 string s = commandStrings[i];
179 NonSwitchStrings.Add(s);
181 if (s == kStopSwitchParsing)
184 if (!ParseString(s, switchForms))
185 NonSwitchStrings.Add(s);
189 public SwitchResult this[int index] { get { return _switches[index]; } }
191 public static int ParseCommand(CommandForm[] commandForms, string commandString,
192 out string postString)
194 for (int i = 0; i < commandForms.Length; i++)
196 string id = commandForms[i].IDString;
197 if (commandForms[i].PostStringMode)
199 if (commandString.IndexOf(id) == 0)
201 postString = commandString.Substring(id.Length);
206 if (commandString == id)
216 static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,
217 string commandString, ArrayList indices)
220 int numUsedChars = 0;
221 for (int i = 0; i < numForms; i++)
223 CommandSubCharsSet charsSet = forms[i];
224 int currentIndex = -1;
225 int len = charsSet.Chars.Length;
226 for (int j = 0; j < len; j++)
228 char c = charsSet.Chars[j];
229 int newIndex = commandString.IndexOf(c);
232 if (currentIndex >= 0)
234 if (commandString.IndexOf(c, newIndex + 1) >= 0)
240 if (currentIndex == -1 && !charsSet.EmptyAllowed)
242 indices.Add(currentIndex);
244 return (numUsedChars == commandString.Length);
246 const char kSwitchID1 = '-';
247 const char kSwitchID2 = '/';
249 const char kSwitchMinus = '-';
250 const string kStopSwitchParsing = "--";
252 static bool IsItSwitchChar(char c)
254 return (c == kSwitchID1 || c == kSwitchID2);
258 public class CommandForm
260 public string IDString = "";
261 public bool PostStringMode = false;
262 public CommandForm(string idString, bool postStringMode)
265 PostStringMode = postStringMode;
269 class CommandSubCharsSet
271 public string Chars = "";
272 public bool EmptyAllowed = false;