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:
Markus Ewald 2009-04-23 20:23:23 +00:00
parent 66b4a762cf
commit f2280629b9
6 changed files with 175 additions and 96 deletions

View File

@ -37,7 +37,6 @@ namespace Nuclex.Support.Licensing {
new LicenseKey(); new LicenseKey();
} }
/// <summary>Validates the correct translation of keys to GUIDs and back</summary> /// <summary>Validates the correct translation of keys to GUIDs and back</summary>
[Test] [Test]
public void TestGuidKeyConversion() { public void TestGuidKeyConversion() {

View File

@ -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> /// <summary>
/// Contains the entire option as it was specified on the command line /// Contains the entire option as it was specified on the command line
/// </summary> /// </summary>

View File

@ -20,12 +20,43 @@ License along with this library
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace Nuclex.Support.Parsing { namespace Nuclex.Support.Parsing {
partial class CommandLine { 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();
}
}
} }

View File

@ -49,20 +49,6 @@ namespace Nuclex.Support.Parsing {
return theParser.arguments; 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> /// <summary>
/// Parses the provided string and adds the parameters found to /// Parses the provided string and adds the parameters found to
/// the command line representation /// 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> /// <summary>
/// Parses a chunk of characters and adds it as an option or a loose value to /// Parses a chunk of characters and adds it as an option or a loose value to
/// the command line representation we're building /// the command line representation we're building

View File

@ -579,6 +579,50 @@ namespace Nuclex.Support.Parsing {
Assert.IsFalse(test.HasArgument("fourth")); 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 } // namespace Nuclex.Support.Parsing

View File

@ -91,26 +91,6 @@ namespace Nuclex.Support.Parsing {
this.arguments = argumentList; 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> /// <summary>Parses the command line arguments from the provided string</summary>
/// <param name="commandLineString">String containing the command line arguments</param> /// <param name="commandLineString">String containing the command line arguments</param>
/// <returns>The parsed command line</returns> /// <returns>The parsed command line</returns>
@ -146,41 +126,101 @@ namespace Nuclex.Support.Parsing {
return (indexOfArgument(name) != -1); return (indexOfArgument(name) != -1);
} }
#if false /// <summary>Adds a value to the command line</summary>
/// <summary>Retrieves the value of the specified argument</summary> /// <param name="value">Value that will be added</param>
/// <param name="name">Name of the argument whose value will be retrieved</param> public void AddValue(string value) {
/// <returns>The value of the specified argument</returns> bool valueContainsSpaces = (value.IndexOfAny(new char[] { ' ', '\t' }) != -1);
public string GetValue(string name) {
int index = indexOfArgument(name); if(valueContainsSpaces) {
if(index == -1) { StringBuilder builder = new StringBuilder(value.Length + 2);
return null; 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? /// <summary>Adds an option to the command line</summary>
Argument argument = this.arguments[index]; /// <param name="name">Name of the option that will be added</param>
if(argument.Value != null) { public void AddOption(string name) {
return argument.Value; AddOption("-", name);
} 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;
} }
/// <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);
} }
// No argument found /// <summary>Adds an option with an assignment to the command line</summary>
return null; /// <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);
} }
#endif
/// <summary>Retrieves the index of the argument with the specified name</summary> /// <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> /// <param name="name">Name of the argument whose index will be returned</param>
@ -197,7 +237,6 @@ namespace Nuclex.Support.Parsing {
return -1; return -1;
} }
/// <summary>Options that were specified on the command line</summary> /// <summary>Options that were specified on the command line</summary>
public IList<Argument> Arguments { public IList<Argument> Arguments {
get { return this.arguments; } get { return this.arguments; }