Last active
February 24, 2019 03:36
-
-
Save yetanotherchris/4747009 to your computer and use it in GitHub Desktop.
Command line argument parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void Main(string[] args) | |
{ | |
string[] example = { @"--arg1=""test"" --arg2= this is wrong --arg3=x --arg4=""value 4""" }; | |
// Default usage | |
CommandLineTokenizer tokenizer = new CommandLineTokenizer(example); | |
Console.WriteLine(tokenizer["arg1"]); | |
Console.WriteLine(tokenizer["arg2"]); // bad tokens are blank strings | |
Console.WriteLine(tokenizer["arg5"]); // unknown tokens will also be blank string | |
// Alternative usage | |
tokenizer = new CommandLineTokenizer(); | |
List<KeyValuePair<string, string>> list = tokenizer.Tokenize(example); | |
} | |
public class CommandLineTokenizer | |
{ | |
private enum State | |
{ | |
None, | |
FirstDash, | |
SecondDash, | |
StartArg, | |
StartArgDoubleQuotes, | |
EndArgDoubleQuotes, | |
StartArgSingleQuotes, | |
EndArgSingleQuotes, | |
Parse | |
} | |
private List<KeyValuePair<string, string>> _tokens; | |
public string this[string key] | |
{ | |
get | |
{ | |
for (int i = 0; i < _tokens.Count; i++) | |
{ | |
if (_tokens[i].Key == key) | |
return _tokens[i].Value; | |
} | |
return ""; | |
} | |
} | |
public CommandLineTokenizer() | |
{ | |
string line = Environment.CommandLine; | |
line = line.Replace("\"" + Process.GetCurrentProcess().MainModule.FileName + "\"", ""); | |
_tokens = Tokenize(line); | |
} | |
public CommandLineTokenizer(string[] args) | |
: this() | |
{ | |
string input = string.Join(" ", args); | |
_tokens = Tokenize(input); | |
} | |
public List<KeyValuePair<string, string>> Tokenize(string input) | |
{ | |
return Pass2(Pass1(input)); | |
} | |
private List<string> Pass1(string input) | |
{ | |
State state = State.None; | |
int start = 0; | |
int end = 0; | |
List<string> list = new List<string>(); | |
for (int i = 0; i < input.Length; i++) | |
{ | |
char current = input[i]; | |
//Console.WriteLine("{0} {1}", current, state); | |
if (input[i] == '-') | |
{ | |
if (state == State.None) | |
{ | |
state = State.FirstDash; | |
} | |
else if (state == State.FirstDash) | |
{ | |
state = State.SecondDash; | |
} | |
else if (state == State.SecondDash) | |
{ | |
state = State.None; | |
start = 0; | |
} | |
} | |
else if (state == State.SecondDash) | |
{ | |
start = i; | |
state = State.StartArg; | |
} | |
else if (current == '"') | |
{ | |
if (state == State.StartArg) | |
{ | |
state = State.StartArgDoubleQuotes; | |
} | |
else if (state == State.StartArgDoubleQuotes) | |
{ | |
state = State.EndArgDoubleQuotes; | |
if (i == input.Length - 1) | |
{ | |
state = State.Parse; | |
end = input.Length; | |
} | |
} | |
} | |
else if (current == '\'') | |
{ | |
if (state == State.StartArg) | |
{ | |
state = State.StartArgSingleQuotes; | |
} | |
else if (state == State.StartArgSingleQuotes) | |
{ | |
state = State.EndArgSingleQuotes; | |
if (i == input.Length - 1) | |
{ | |
state = State.Parse; | |
end = input.Length; | |
} | |
} | |
} | |
else if ((state == State.EndArgSingleQuotes || state == State.EndArgDoubleQuotes) && (current == ' ' || i == input.Length - 1)) | |
{ | |
end = i + 1; | |
state = State.Parse; | |
} | |
else if (state == State.StartArg && (current == ' ' || i == input.Length - 1)) | |
{ | |
end = i + 1; // get past this current char | |
state = State.Parse; | |
} | |
if (state == State.Parse) | |
{ | |
state = State.None; | |
list.Add(input.Substring(start, end - start)); | |
} | |
} | |
return list; | |
} | |
private List<KeyValuePair<string, string>> Pass2(List<string> list) | |
{ | |
List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>(); | |
foreach (string item in list) | |
{ | |
int equals = item.IndexOf("="); | |
if (equals > -1 && item.Length >= 3) | |
{ | |
string key = item.Substring(0, equals); | |
string value = item.Substring(equals + 1); | |
KeyValuePair<string, string> pair = new KeyValuePair<string, string>(key, value); | |
result.Add(pair); | |
} | |
} | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment