A special command line parser class that automatically parses command lines specified in a particular way
// Parse command line arguments in the form // /xxx // -xxx // OR // /xxx:yyy // -xxx:yyy // where xxx is a parameter name and yyy, when present, is a value to associate with it // The actual command line argument is case insensitive (but not the value) // so /username:Bob is the same as /USERNAME:Bob public class CommandLineParser { readonly Dictionary<string, string> arguments = new Dictionary<string, string>(); public void ParseCommandLineArguments( params string[] args ) { const int NOTFOUND = -1; //string[] args = Environment.GetCommandLineArgs(); Debug.WriteLine( "Args:" + string.Join( ",", args ) ); int ix = 0; foreach ( string arg in args ) { Debug.WriteLine( "arg[" + ix++.ToString() + "]=\'" + arg + "\'" ); } foreach ( string rawArg in args ) { // Get rid of whitespace chars at the beginning and end string arg = rawArg.Trim(); bool argFound = ( arg.Length >= 2 ) && ( arg[ 0 ] == '/' || arg[ 0 ] == '-' ); if ( !argFound ) continue; string argument = arg.Substring( 1 ); int end = argument.IndexOf( ':' ); string paramName = ( end > -1 ) ? argument.Substring( 0, end ) : argument; if ( ( end == NOTFOUND ) && ( paramName.Length > 0 ) ) { arguments.Add( paramName.ToUpperInvariant(), "" ); } else { string value = argument.Substring( end + 1 ); arguments.Add( paramName.ToUpperInvariant(), value ); } } Debug.WriteLine( "Processed command line args:" ); foreach ( string argName in arguments.Keys ) { Debug.WriteLine( argName + " = " + arguments[ argName ] ); } } public bool GetArgument( string arg, out string value ) { value = ""; return arguments.TryGetValue( arg.ToUpperInvariant(), out value ); } // eg '/u' could select the argument /username:Jim as long as no other arguments starts with 'u' public bool GetUniqueArgumentStartingWith( string startsWith, out string value ) { value = ""; bool res = string.IsNullOrEmpty( startsWith.Trim() ); if ( !res ) { var keys = arguments.Keys.Where( ky => ky.StartsWith( startsWith.ToUpperInvariant() ) ).ToList(); res = ( keys.Count == 1 ); if ( res ) { res = arguments.TryGetValue( keys[ 0 ], out value ); } } return res; } public bool HasUniqueArgumentStartingWith( string startsWith ) { bool res = !string.IsNullOrEmpty( startsWith.Trim() ); if ( res ) { var keys = arguments.Keys.Where( ky => ky.StartsWith( startsWith.ToUpperInvariant() ) ); res = ( keys.Count() == 1 ); } return res; } public bool HasArgument( string arg ) { return arguments.ContainsKey( arg.ToUpperInvariant() ); } public IEnumerable<KeyValuePair<string, string>> Arguments() { foreach ( var entry in arguments ) { yield return entry; } } }Unit testss that accomapny and demonstrate the use of the class:
[ TestFixture ] public class CommandLineParserUnitTests { [ Test ] public void SeveralValidArgsTest() { CommandLineParser clp = new CommandLineParser(); clp.ParseCommandLineArguments( "/user:John", "-password:All0aJadgar", "-IncludeMetaData" ); Assert.That( clp.HasArgument( "IncludeMetaData" ) ); string value; bool res = clp.GetArgument( "user", out value ); Assert.IsTrue( res ); Assert.That( value == "John" ); res = clp.GetArgument( "smugering", out value ); Assert.IsFalse( res ); } [ Test ] public void EmptyArgAndValueTest() { CommandLineParser clp = new CommandLineParser(); clp.ParseCommandLineArguments( "/:" ); Assert.That( !clp.HasArgument( ":" ) ); } [ Test ] public void NoValueSpecifiedTest() { CommandLineParser clp = new CommandLineParser(); clp.ParseCommandLineArguments( "/dufftest:" ); string value; Assert.That( clp.GetArgument( "dufftest", out value ) ); Assert.That( value.Length == 0 ); Assert.That( clp.HasArgument( "dufftest" ) ); } }
No comments:
Post a Comment