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
|
@ -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() {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -579,8 +579,52 @@ 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
|
||||||
|
|
||||||
#endif // UNITTEST
|
#endif // UNITTEST
|
||||||
|
|
|
@ -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?
|
|
||||||
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>
|
/// <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; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user