The command line class can now also be used to build a command line (for example, to pass it to another program); removed dead code from the command line class
git-svn-id: file:///srv/devel/repo-conversion/nusu@132 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
		
							parent
							
								
									66b4a762cf
								
							
						
					
					
						commit
						f2280629b9
					
				
					 6 changed files with 175 additions and 96 deletions
				
			
		|  | @ -37,7 +37,6 @@ namespace Nuclex.Support.Licensing { | |||
|       new LicenseKey(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary>Validates the correct translation of keys to GUIDs and back</summary> | ||||
|     [Test] | ||||
|     public void TestGuidKeyConversion() { | ||||
|  |  | |||
|  | @ -140,6 +140,11 @@ namespace Nuclex.Support.Parsing { | |||
|         } | ||||
|       } | ||||
| 
 | ||||
|       /// <summary>The raw length of the command line argument</summary> | ||||
|       internal int RawLength { | ||||
|         get { return this.raw.Count; } | ||||
|       } | ||||
| 
 | ||||
|       /// <summary> | ||||
|       ///   Contains the entire option as it was specified on the command line | ||||
|       /// </summary> | ||||
|  |  | |||
|  | @ -20,12 +20,43 @@ License along with this library | |||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace Nuclex.Support.Parsing { | ||||
| 
 | ||||
|   partial class CommandLine { | ||||
| 
 | ||||
|     internal static class Formatter { } | ||||
|     /// <summary>Formats a command line instance into a string</summary> | ||||
|     internal static class Formatter { | ||||
| 
 | ||||
|       /// <summary> | ||||
|       ///   Formats all arguments in the provided command line instance into a string | ||||
|       /// </summary> | ||||
|       /// <param name="commandLine">Command line instance that will be formatted</param> | ||||
|       /// <returns>All arguments in the command line instance as a string</returns> | ||||
|       public static string FormatCommandLine(CommandLine commandLine) { | ||||
|         int totalLength = 0; | ||||
|         for(int index = 0; index < commandLine.arguments.Count; ++index) { | ||||
|           if(index != 0) { | ||||
|             ++totalLength; // For spacing between arguments | ||||
|           } | ||||
| 
 | ||||
|           totalLength += commandLine.arguments[index].RawLength; | ||||
|         } | ||||
| 
 | ||||
|         StringBuilder builder = new StringBuilder(totalLength); | ||||
|         for(int index = 0; index < commandLine.arguments.Count; ++index) { | ||||
|           if(index != 0) { | ||||
|             builder.Append(' '); | ||||
|           } | ||||
| 
 | ||||
|           builder.Append(commandLine.arguments[index].Raw); | ||||
|         } | ||||
| 
 | ||||
|         return builder.ToString(); | ||||
|       } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,20 +49,6 @@ namespace Nuclex.Support.Parsing { | |||
|         return theParser.arguments; | ||||
|       } | ||||
| 
 | ||||
| #if ENABLE_TOKENIZED_COMMAND_LINE_PARSING // don't enable, it's broken! | ||||
|       /// <summary>Parses a string containing command line arguments</summary> | ||||
|       /// <param name="commandLineArguments">Command line tokens that will be parsed</param> | ||||
|       /// <param name="windowsMode">Whether the / character initiates an argument</param> | ||||
|       /// <returns>The parsed command line arguments from the string</returns> | ||||
|       public static List<CommandLine.Argument> Parse( | ||||
|         string[] commandLineArguments, bool windowsMode | ||||
|       ) { | ||||
|         Parser theParser = new Parser(windowsMode); | ||||
|         theParser.parseSplitCommandLine(commandLineArguments); | ||||
|         return theParser.arguments; | ||||
|       } | ||||
| #endif // ENABLE_TOKENIZED_COMMAND_LINE_PARSING | ||||
| 
 | ||||
|       /// <summary> | ||||
|       ///   Parses the provided string and adds the parameters found to | ||||
|       ///   the command line representation | ||||
|  | @ -94,31 +80,6 @@ namespace Nuclex.Support.Parsing { | |||
|         } | ||||
|       } | ||||
| 
 | ||||
| #if ENABLE_TOKENIZED_COMMAND_LINE_PARSING // don't enable, it's broken! | ||||
|       /// <summary> | ||||
|       ///   Parses the command line from a series pre-split argument tokens | ||||
|       /// </summary> | ||||
|       /// <param name="commandLineParts">Split argument tokens that will be parsed</param> | ||||
|       private void parseSplitCommandLine(string[] commandLineParts) { | ||||
|         if(commandLineParts == null) { | ||||
|           return; | ||||
|         } | ||||
| 
 | ||||
|         // Walk through the command line character by character and gather | ||||
|         // the parameters and values to build the command line representation from | ||||
|         for(int index = 0; index < commandLineParts.Length; ++index) { | ||||
| 
 | ||||
|           if(commandLineParts[index] != null) { | ||||
|             int characterIndex = 0; | ||||
|             parseChunk(commandLineParts[index], ref characterIndex); | ||||
| 
 | ||||
|             Debug.Assert(characterIndex == commandLineParts[index].Length); | ||||
|           } | ||||
| 
 | ||||
|         } | ||||
|       } | ||||
| #endif // ENABLE_TOKENIZED_COMMAND_LINE_PARSING | ||||
| 
 | ||||
|       /// <summary> | ||||
|       ///   Parses a chunk of characters and adds it as an option or a loose value to | ||||
|       ///   the command line representation we're building | ||||
|  |  | |||
|  | @ -579,6 +579,50 @@ namespace Nuclex.Support.Parsing { | |||
|       Assert.IsFalse(test.HasArgument("fourth")); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Tests whether a command line can be built with the command line class | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestCommandLineFormatting() { | ||||
|       CommandLine commandLine = new CommandLine(); | ||||
| 
 | ||||
|       commandLine.AddValue("single"); | ||||
|       commandLine.AddValue("with space"); | ||||
|       commandLine.AddOption("option"); | ||||
|       commandLine.AddOption("@@", "extravagant-option"); | ||||
|       commandLine.AddAssignment("name", "value"); | ||||
|       commandLine.AddAssignment("name", "value with spaces"); | ||||
|       commandLine.AddAssignment("@@", "name", "value"); | ||||
|       commandLine.AddAssignment("@@", "name", "value with spaces"); | ||||
| 
 | ||||
|       Assert.AreEqual(8, commandLine.Arguments.Count); | ||||
|       Assert.AreEqual("single", commandLine.Arguments[0].Value); | ||||
|       Assert.AreEqual("with space", commandLine.Arguments[1].Value); | ||||
|       Assert.AreEqual("option", commandLine.Arguments[2].Name); | ||||
|       Assert.AreEqual("@@", commandLine.Arguments[3].Initiator); | ||||
|       Assert.AreEqual("extravagant-option", commandLine.Arguments[3].Name); | ||||
|       Assert.AreEqual("name", commandLine.Arguments[4].Name); | ||||
|       Assert.AreEqual("value", commandLine.Arguments[4].Value); | ||||
|       Assert.AreEqual("name", commandLine.Arguments[5].Name); | ||||
|       Assert.AreEqual("value with spaces", commandLine.Arguments[5].Value); | ||||
|       Assert.AreEqual("@@", commandLine.Arguments[6].Initiator); | ||||
|       Assert.AreEqual("name", commandLine.Arguments[6].Name); | ||||
|       Assert.AreEqual("value", commandLine.Arguments[6].Value); | ||||
|       Assert.AreEqual("name", commandLine.Arguments[7].Name); | ||||
|       Assert.AreEqual("@@", commandLine.Arguments[7].Initiator); | ||||
|       Assert.AreEqual("value with spaces", commandLine.Arguments[7].Value); | ||||
| 
 | ||||
|       string commandLineString = commandLine.ToString(); | ||||
|       Assert.AreEqual( | ||||
|         "single \"with space\" " + | ||||
|         "-option @@extravagant-option " + | ||||
|         "-name=value -name=\"value with spaces\" " + | ||||
|         "@@name=value @@name=\"value with spaces\"", | ||||
|         commandLineString | ||||
|       ); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| } // namespace Nuclex.Support.Parsing | ||||
|  |  | |||
|  | @ -91,26 +91,6 @@ namespace Nuclex.Support.Parsing { | |||
|       this.arguments = argumentList; | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_TOKENIZED_COMMAND_LINE_PARSING // don't enable, it's broken! | ||||
|     /// <summary>Parses the command line arguments from the provided string</summary> | ||||
|     /// <param name="commandLineArguments">Command line tokens that will be parsed</param> | ||||
|     /// <returns>The parsed command line</returns> | ||||
|     public static CommandLine Parse(string[] commandLineArguments) { | ||||
|       bool windowsMode = (Path.DirectorySeparatorChar != '/'); | ||||
|       return Parse(commandLineArguments, windowsMode); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Parses the command line arguments from the provided string</summary> | ||||
|     /// <param name="commandLineArguments">Command line tokens that will be parsed</param> | ||||
|     /// <param name="windowsMode">Whether the / character initiates an argument</param> | ||||
|     /// <returns>The parsed command line</returns> | ||||
|     public static CommandLine Parse(string[] commandLineArguments, bool windowsMode) { | ||||
|       return new CommandLine( | ||||
|         Parser.Parse(commandLineArguments, windowsMode) | ||||
|       ); | ||||
|     } | ||||
| #endif // ENABLE_TOKENIZED_COMMAND_LINE_PARSING | ||||
| 
 | ||||
|     /// <summary>Parses the command line arguments from the provided string</summary> | ||||
|     /// <param name="commandLineString">String containing the command line arguments</param> | ||||
|     /// <returns>The parsed command line</returns> | ||||
|  | @ -146,41 +126,101 @@ namespace Nuclex.Support.Parsing { | |||
|       return (indexOfArgument(name) != -1); | ||||
|     } | ||||
| 
 | ||||
| #if false | ||||
|     /// <summary>Retrieves the value of the specified argument</summary> | ||||
|     /// <param name="name">Name of the argument whose value will be retrieved</param> | ||||
|     /// <returns>The value of the specified argument</returns> | ||||
|     public string GetValue(string name) { | ||||
|       int index = indexOfArgument(name); | ||||
|       if(index == -1) { | ||||
|         return null; | ||||
|     /// <summary>Adds a value to the command line</summary> | ||||
|     /// <param name="value">Value that will be added</param> | ||||
|     public void AddValue(string value) { | ||||
|       bool valueContainsSpaces = (value.IndexOfAny(new char[] { ' ', '\t' }) != -1); | ||||
| 
 | ||||
|       if(valueContainsSpaces) { | ||||
|         StringBuilder builder = new StringBuilder(value.Length + 2); | ||||
|         builder.Append('"'); | ||||
|         builder.Append(value); | ||||
|         builder.Append('"'); | ||||
| 
 | ||||
|         this.arguments.Add( | ||||
|           Argument.ValueOnly( | ||||
|             new StringSegment(builder.ToString(), 0, value.Length + 2), | ||||
|             1, | ||||
|             value.Length | ||||
|           ) | ||||
|         ); | ||||
|       } else { | ||||
|         this.arguments.Add( | ||||
|           Argument.ValueOnly(new StringSegment(value), 0, value.Length) | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       // Does this argument have a value? | ||||
|       Argument argument = this.arguments[index]; | ||||
|       if(argument.Value != null) { | ||||
|         return argument.Value; | ||||
|       } else { // No, it might be a spaced argument | ||||
| 
 | ||||
|         // See if anything more follows this argument | ||||
|         ++index; | ||||
|         if(index < this.arguments.Count) { | ||||
| 
 | ||||
|           // If something follows the argument, and it is not an option of its own, | ||||
|           // use its value as the value for the preceding argument | ||||
|           argument = this.arguments[index]; | ||||
|           if(argument.Name == null) { | ||||
|             return argument.Value; | ||||
|           } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|       } | ||||
| 
 | ||||
|       // No argument found | ||||
|       return null; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     /// <summary>Adds an option to the command line</summary> | ||||
|     /// <param name="name">Name of the option that will be added</param> | ||||
|     public void AddOption(string name) { | ||||
|       AddOption("-", name); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Adds an option to the command line</summary> | ||||
|     /// <param name="initiator">Initiator that will be used to start the option</param> | ||||
|     /// <param name="name">Name of the option that will be added</param> | ||||
|     public void AddOption(string initiator, string name) { | ||||
|       StringBuilder builder = new StringBuilder( | ||||
|         initiator.Length + name.Length | ||||
|       ); | ||||
|       builder.Append(initiator); | ||||
|       builder.Append(name); | ||||
| 
 | ||||
|       this.arguments.Add( | ||||
|         Argument.OptionOnly( | ||||
|           new StringSegment(builder.ToString()), | ||||
|           initiator.Length, | ||||
|           name.Length | ||||
|         ) | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Adds an option with an assignment to the command line</summary> | ||||
|     /// <param name="name">Name of the option that will be added</param> | ||||
|     /// <param name="value">Value that will be assigned to the option</param> | ||||
|     public void AddAssignment(string name, string value) { | ||||
|       AddAssignment("-", name, value); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Adds an option with an assignment to the command line</summary> | ||||
|     /// <param name="initiator">Initiator that will be used to start the option</param> | ||||
|     /// <param name="name">Name of the option that will be added</param> | ||||
|     /// <param name="value">Value that will be assigned to the option</param> | ||||
|     public void AddAssignment(string initiator, string name, string value) { | ||||
|       bool valueContainsSpaces = (value.IndexOfAny(new char[] { ' ', '\t' }) != -1); | ||||
|       StringBuilder builder = new StringBuilder( | ||||
|         initiator.Length + name.Length + 1 + value.Length + | ||||
|           (valueContainsSpaces ? 2 : 0) | ||||
|       ); | ||||
|       builder.Append(initiator); | ||||
|       builder.Append(name); | ||||
|       builder.Append('='); | ||||
|       if(valueContainsSpaces) { | ||||
|         builder.Append('"'); | ||||
|         builder.Append(value); | ||||
|         builder.Append('"'); | ||||
|       } else { | ||||
|         builder.Append(value); | ||||
|       } | ||||
| 
 | ||||
|       this.arguments.Add( | ||||
|         new Argument( | ||||
|           new StringSegment(builder.ToString()), | ||||
|           initiator.Length, | ||||
|           name.Length, | ||||
|           initiator.Length + name.Length + 1 + | ||||
|             (valueContainsSpaces ? 1 : 0), | ||||
|           value.Length | ||||
|         ) | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Returns a string that contains the entire command line</summary> | ||||
|     /// <returns>The entire command line as a single string</returns> | ||||
|     public override string ToString() { | ||||
|       return Formatter.FormatCommandLine(this); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Retrieves the index of the argument with the specified name</summary> | ||||
|     /// <param name="name">Name of the argument whose index will be returned</param> | ||||
|  | @ -197,7 +237,6 @@ namespace Nuclex.Support.Parsing { | |||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary>Options that were specified on the command line</summary> | ||||
|     public IList<Argument> Arguments { | ||||
|       get { return this.arguments; } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue