| // CommandLineParser.cs | 
|   | 
| using System; | 
| using System.Collections; | 
|   | 
| namespace SevenZip.CommandLineParser | 
| { | 
|     public enum SwitchType | 
|     { | 
|         Simple, | 
|         PostMinus, | 
|         LimitedPostString, | 
|         UnLimitedPostString, | 
|         PostChar | 
|     } | 
|   | 
|     public class SwitchForm | 
|     { | 
|         public string IDString; | 
|         public SwitchType Type; | 
|         public bool Multi; | 
|         public int MinLen; | 
|         public int MaxLen; | 
|         public string PostCharSet; | 
|   | 
|         public SwitchForm(string idString, SwitchType type, bool multi, | 
|             int minLen, int maxLen, string postCharSet) | 
|         { | 
|             IDString = idString; | 
|             Type = type; | 
|             Multi = multi; | 
|             MinLen = minLen; | 
|             MaxLen = maxLen; | 
|             PostCharSet = postCharSet; | 
|         } | 
|         public SwitchForm(string idString, SwitchType type, bool multi, int minLen): | 
|             this(idString, type, multi, minLen, 0, "") | 
|         { | 
|         } | 
|         public SwitchForm(string idString, SwitchType type, bool multi): | 
|             this(idString, type, multi, 0) | 
|         { | 
|         } | 
|     } | 
|   | 
|     public class SwitchResult | 
|     { | 
|         public bool ThereIs; | 
|         public bool WithMinus; | 
|         public ArrayList PostStrings = new ArrayList(); | 
|         public int PostCharIndex; | 
|         public SwitchResult() | 
|         { | 
|             ThereIs = false; | 
|         } | 
|     } | 
|   | 
|     public class Parser | 
|     { | 
|         public ArrayList NonSwitchStrings = new ArrayList(); | 
|         SwitchResult[] _switches; | 
|   | 
|         public Parser(int numSwitches) | 
|         { | 
|             _switches = new SwitchResult[numSwitches]; | 
|             for (int i = 0; i < numSwitches; i++) | 
|                 _switches[i] = new SwitchResult(); | 
|         } | 
|   | 
|         bool ParseString(string srcString, SwitchForm[] switchForms) | 
|         { | 
|             int len = srcString.Length; | 
|             if (len == 0) | 
|                 return false; | 
|             int pos = 0; | 
|             if (!IsItSwitchChar(srcString[pos])) | 
|                 return false; | 
|             while (pos < len) | 
|             { | 
|                 if (IsItSwitchChar(srcString[pos])) | 
|                     pos++; | 
|                 const int kNoLen = -1; | 
|                 int matchedSwitchIndex = 0; | 
|                 int maxLen = kNoLen; | 
|                 for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++) | 
|                 { | 
|                     int switchLen = switchForms[switchIndex].IDString.Length; | 
|                     if (switchLen <= maxLen || pos + switchLen > len) | 
|                         continue; | 
|                     if (String.Compare(switchForms[switchIndex].IDString, 0, | 
|                             srcString, pos, switchLen, true) == 0) | 
|                     { | 
|                         matchedSwitchIndex = switchIndex; | 
|                         maxLen = switchLen; | 
|                     } | 
|                 } | 
|                 if (maxLen == kNoLen) | 
|                     throw new Exception("maxLen == kNoLen"); | 
|                 SwitchResult matchedSwitch = _switches[matchedSwitchIndex]; | 
|                 SwitchForm switchForm = switchForms[matchedSwitchIndex]; | 
|                 if ((!switchForm.Multi) && matchedSwitch.ThereIs) | 
|                     throw new Exception("switch must be single"); | 
|                 matchedSwitch.ThereIs = true; | 
|                 pos += maxLen; | 
|                 int tailSize = len - pos; | 
|                 SwitchType type = switchForm.Type; | 
|                 switch (type) | 
|                 { | 
|                     case SwitchType.PostMinus: | 
|                         { | 
|                             if (tailSize == 0) | 
|                                 matchedSwitch.WithMinus = false; | 
|                             else | 
|                             { | 
|                                 matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus); | 
|                                 if (matchedSwitch.WithMinus) | 
|                                     pos++; | 
|                             } | 
|                             break; | 
|                         } | 
|                     case SwitchType.PostChar: | 
|                         { | 
|                             if (tailSize < switchForm.MinLen) | 
|                                 throw new Exception("switch is not full"); | 
|                             string charSet = switchForm.PostCharSet; | 
|                             const int kEmptyCharValue = -1; | 
|                             if (tailSize == 0) | 
|                                 matchedSwitch.PostCharIndex = kEmptyCharValue; | 
|                             else | 
|                             { | 
|                                 int index = charSet.IndexOf(srcString[pos]); | 
|                                 if (index < 0) | 
|                                     matchedSwitch.PostCharIndex = kEmptyCharValue; | 
|                                 else | 
|                                 { | 
|                                     matchedSwitch.PostCharIndex = index; | 
|                                     pos++; | 
|                                 } | 
|                             } | 
|                             break; | 
|                         } | 
|                     case SwitchType.LimitedPostString: | 
|                     case SwitchType.UnLimitedPostString: | 
|                         { | 
|                             int minLen = switchForm.MinLen; | 
|                             if (tailSize < minLen) | 
|                                 throw new Exception("switch is not full"); | 
|                             if (type == SwitchType.UnLimitedPostString) | 
|                             { | 
|                                 matchedSwitch.PostStrings.Add(srcString.Substring(pos)); | 
|                                 return true; | 
|                             } | 
|                             String stringSwitch = srcString.Substring(pos, minLen); | 
|                             pos += minLen; | 
|                             for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++) | 
|                             { | 
|                                 char c = srcString[pos]; | 
|                                 if (IsItSwitchChar(c)) | 
|                                     break; | 
|                                 stringSwitch += c; | 
|                             } | 
|                             matchedSwitch.PostStrings.Add(stringSwitch); | 
|                             break; | 
|                         } | 
|                 } | 
|             } | 
|             return true; | 
|   | 
|         } | 
|   | 
|         public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings) | 
|         { | 
|             int numCommandStrings = commandStrings.Length; | 
|             bool stopSwitch = false; | 
|             for (int i = 0; i < numCommandStrings; i++) | 
|             { | 
|                 string s = commandStrings[i]; | 
|                 if (stopSwitch) | 
|                     NonSwitchStrings.Add(s); | 
|                 else | 
|                     if (s == kStopSwitchParsing) | 
|                     stopSwitch = true; | 
|                 else | 
|                     if (!ParseString(s, switchForms)) | 
|                     NonSwitchStrings.Add(s); | 
|             } | 
|         } | 
|   | 
|         public SwitchResult this[int index] { get { return _switches[index]; } } | 
|   | 
|         public static int ParseCommand(CommandForm[] commandForms, string commandString, | 
|             out string postString) | 
|         { | 
|             for (int i = 0; i < commandForms.Length; i++) | 
|             { | 
|                 string id = commandForms[i].IDString; | 
|                 if (commandForms[i].PostStringMode) | 
|                 { | 
|                     if (commandString.IndexOf(id) == 0) | 
|                     { | 
|                         postString = commandString.Substring(id.Length); | 
|                         return i; | 
|                     } | 
|                 } | 
|                 else | 
|                     if (commandString == id) | 
|                 { | 
|                     postString = ""; | 
|                     return i; | 
|                 } | 
|             } | 
|             postString = ""; | 
|             return -1; | 
|         } | 
|   | 
|         static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms, | 
|             string commandString, ArrayList indices) | 
|         { | 
|             indices.Clear(); | 
|             int numUsedChars = 0; | 
|             for (int i = 0; i < numForms; i++) | 
|             { | 
|                 CommandSubCharsSet charsSet = forms[i]; | 
|                 int currentIndex = -1; | 
|                 int len = charsSet.Chars.Length; | 
|                 for (int j = 0; j < len; j++) | 
|                 { | 
|                     char c = charsSet.Chars[j]; | 
|                     int newIndex = commandString.IndexOf(c); | 
|                     if (newIndex >= 0) | 
|                     { | 
|                         if (currentIndex >= 0) | 
|                             return false; | 
|                         if (commandString.IndexOf(c, newIndex + 1) >= 0) | 
|                             return false; | 
|                         currentIndex = j; | 
|                         numUsedChars++; | 
|                     } | 
|                 } | 
|                 if (currentIndex == -1 && !charsSet.EmptyAllowed) | 
|                     return false; | 
|                 indices.Add(currentIndex); | 
|             } | 
|             return (numUsedChars == commandString.Length); | 
|         } | 
|         const char kSwitchID1 = '-'; | 
|         const char kSwitchID2 = '/'; | 
|   | 
|         const char kSwitchMinus = '-'; | 
|         const string kStopSwitchParsing = "--"; | 
|   | 
|         static bool IsItSwitchChar(char c) | 
|         { | 
|             return (c == kSwitchID1 || c == kSwitchID2); | 
|         } | 
|     } | 
|   | 
|     public class CommandForm | 
|     { | 
|         public string IDString = ""; | 
|         public bool PostStringMode = false; | 
|         public CommandForm(string idString, bool postStringMode) | 
|         { | 
|             IDString = idString; | 
|             PostStringMode = postStringMode; | 
|         } | 
|     } | 
|   | 
|     class CommandSubCharsSet | 
|     { | 
|         public string Chars = ""; | 
|         public bool EmptyAllowed = false; | 
|     } | 
| } |