tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CommandLineParser.cs (6916B)


      1 // CommandLineParser.cs
      2 
      3 using System;
      4 using System.Collections;
      5 
      6 namespace SevenZip.CommandLineParser
      7 {
      8 public enum SwitchType
      9 {
     10 	Simple,
     11 	PostMinus,
     12 	LimitedPostString,
     13 	UnLimitedPostString,
     14 	PostChar
     15 }
     16 
     17 public class SwitchForm
     18 {
     19 	public string IDString;
     20 	public SwitchType Type;
     21 	public bool Multi;
     22 	public int MinLen;
     23 	public int MaxLen;
     24 	public string PostCharSet;
     25 
     26 	public SwitchForm(string idString, SwitchType type, bool multi,
     27 		int minLen, int maxLen, string postCharSet)
     28 	{
     29 		IDString = idString;
     30 		Type = type;
     31 		Multi = multi;
     32 		MinLen = minLen;
     33 		MaxLen = maxLen;
     34 		PostCharSet = postCharSet;
     35 	}
     36 	public SwitchForm(string idString, SwitchType type, bool multi, int minLen):
     37 		this(idString, type, multi, minLen, 0, "")
     38 	{
     39 	}
     40 	public SwitchForm(string idString, SwitchType type, bool multi):
     41 		this(idString, type, multi, 0)
     42 	{
     43 	}
     44 }
     45 
     46 public class SwitchResult
     47 {
     48 	public bool ThereIs;
     49 	public bool WithMinus;
     50 	public ArrayList PostStrings = new ArrayList();
     51 	public int PostCharIndex;
     52 	public SwitchResult()
     53 	{
     54 		ThereIs = false;
     55 	}
     56 }
     57 
     58 public class Parser
     59 {
     60 	public ArrayList NonSwitchStrings = new ArrayList();
     61 	SwitchResult[] _switches;
     62 
     63 	public Parser(int numSwitches)
     64 	{
     65 		_switches = new SwitchResult[numSwitches];
     66 		for (int i = 0; i < numSwitches; i++)
     67 			_switches[i] = new SwitchResult();
     68 	}
     69 
     70 	bool ParseString(string srcString, SwitchForm[] switchForms)
     71 	{
     72 		int len = srcString.Length;
     73 		if (len == 0)
     74 			return false;
     75 		int pos = 0;
     76 		if (!IsItSwitchChar(srcString[pos]))
     77 			return false;
     78 		while (pos < len)
     79 		{
     80 			if (IsItSwitchChar(srcString[pos]))
     81 				pos++;
     82 			const int kNoLen = -1;
     83 			int matchedSwitchIndex = 0;
     84 			int maxLen = kNoLen;
     85 			for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
     86 			{
     87 				int switchLen = switchForms[switchIndex].IDString.Length;
     88 				if (switchLen <= maxLen || pos + switchLen > len)
     89 					continue;
     90 				if (String.Compare(switchForms[switchIndex].IDString, 0,
     91 						srcString, pos, switchLen, true) == 0)
     92 				{
     93 					matchedSwitchIndex = switchIndex;
     94 					maxLen = switchLen;
     95 				}
     96 			}
     97 			if (maxLen == kNoLen)
     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;
    104 			pos += maxLen;
    105 			int tailSize = len - pos;
    106 			SwitchType type = switchForm.Type;
    107 			switch (type)
    108 			{
    109 				case SwitchType.PostMinus:
    110 					{
    111 						if (tailSize == 0)
    112 							matchedSwitch.WithMinus = false;
    113 						else
    114 						{
    115 							matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
    116 							if (matchedSwitch.WithMinus)
    117 								pos++;
    118 						}
    119 						break;
    120 					}
    121 				case SwitchType.PostChar:
    122 					{
    123 						if (tailSize < switchForm.MinLen)
    124 							throw new Exception("switch is not full");
    125 						string charSet = switchForm.PostCharSet;
    126 						const int kEmptyCharValue = -1;
    127 						if (tailSize == 0)
    128 							matchedSwitch.PostCharIndex = kEmptyCharValue;
    129 						else
    130 						{
    131 							int index = charSet.IndexOf(srcString[pos]);
    132 							if (index < 0)
    133 								matchedSwitch.PostCharIndex = kEmptyCharValue;
    134 							else
    135 							{
    136 								matchedSwitch.PostCharIndex = index;
    137 								pos++;
    138 							}
    139 						}
    140 						break;
    141 					}
    142 				case SwitchType.LimitedPostString:
    143 				case SwitchType.UnLimitedPostString:
    144 					{
    145 						int minLen = switchForm.MinLen;
    146 						if (tailSize < minLen)
    147 							throw new Exception("switch is not full");
    148 						if (type == SwitchType.UnLimitedPostString)
    149 						{
    150 							matchedSwitch.PostStrings.Add(srcString.Substring(pos));
    151 							return true;
    152 						}
    153 						String stringSwitch = srcString.Substring(pos, minLen);
    154 						pos += minLen;
    155 						for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
    156 						{
    157 							char c = srcString[pos];
    158 							if (IsItSwitchChar(c))
    159 								break;
    160 							stringSwitch += c;
    161 						}
    162 						matchedSwitch.PostStrings.Add(stringSwitch);
    163 						break;
    164 					}
    165 			}
    166 		}
    167 		return true;
    168 
    169 	}
    170 
    171 	public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
    172 	{
    173 		int numCommandStrings = commandStrings.Length;
    174 		bool stopSwitch = false;
    175 		for (int i = 0; i < numCommandStrings; i++)
    176 		{
    177 			string s = commandStrings[i];
    178 			if (stopSwitch)
    179 				NonSwitchStrings.Add(s);
    180 			else
    181 				if (s == kStopSwitchParsing)
    182 				stopSwitch = true;
    183 			else
    184 				if (!ParseString(s, switchForms))
    185 				NonSwitchStrings.Add(s);
    186 		}
    187 	}
    188 
    189 	public SwitchResult this[int index] { get { return _switches[index]; } }
    190 
    191 	public static int ParseCommand(CommandForm[] commandForms, string commandString,
    192 		out string postString)
    193 	{
    194 		for (int i = 0; i < commandForms.Length; i++)
    195 		{
    196 			string id = commandForms[i].IDString;
    197 			if (commandForms[i].PostStringMode)
    198 			{
    199 				if (commandString.IndexOf(id) == 0)
    200 				{
    201 					postString = commandString.Substring(id.Length);
    202 					return i;
    203 				}
    204 			}
    205 			else
    206 				if (commandString == id)
    207 			{
    208 				postString = "";
    209 				return i;
    210 			}
    211 		}
    212 		postString = "";
    213 		return -1;
    214 	}
    215 
    216 	static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,
    217 		string commandString, ArrayList indices)
    218 	{
    219 		indices.Clear();
    220 		int numUsedChars = 0;
    221 		for (int i = 0; i < numForms; i++)
    222 		{
    223 			CommandSubCharsSet charsSet = forms[i];
    224 			int currentIndex = -1;
    225 			int len = charsSet.Chars.Length;
    226 			for (int j = 0; j < len; j++)
    227 			{
    228 				char c = charsSet.Chars[j];
    229 				int newIndex = commandString.IndexOf(c);
    230 				if (newIndex >= 0)
    231 				{
    232 					if (currentIndex >= 0)
    233 						return false;
    234 					if (commandString.IndexOf(c, newIndex + 1) >= 0)
    235 						return false;
    236 					currentIndex = j;
    237 					numUsedChars++;
    238 				}
    239 			}
    240 			if (currentIndex == -1 && !charsSet.EmptyAllowed)
    241 				return false;
    242 			indices.Add(currentIndex);
    243 		}
    244 		return (numUsedChars == commandString.Length);
    245 	}
    246 	const char kSwitchID1 = '-';
    247 	const char kSwitchID2 = '/';
    248 
    249 	const char kSwitchMinus = '-';
    250 	const string kStopSwitchParsing = "--";
    251 
    252 	static bool IsItSwitchChar(char c)
    253 	{
    254 		return (c == kSwitchID1 || c == kSwitchID2);
    255 	}
    256 }
    257 
    258 public class CommandForm
    259 {
    260 	public string IDString = "";
    261 	public bool PostStringMode = false;
    262 	public CommandForm(string idString, bool postStringMode)
    263 	{
    264 		IDString = idString;
    265 		PostStringMode = postStringMode;
    266 	}
    267 }
    268 
    269 class CommandSubCharsSet
    270 {
    271 	public string Chars = "";
    272 	public bool EmptyAllowed = false;
    273 }
    274 }