using System.Collections.Generic;
namespace Semmle.Util
{
///
/// Represents a parsed set of command line options.
///
public interface ICommandLineOptions
{
///
/// Handle an option of the form "--threads 5" or "--threads:5"
///
/// The name of the key. This is case sensitive.
/// The supplied value.
/// True if the option was handled, or false otherwise.
bool handleOption(string key, string value);
///
/// Handle a flag of the form "--cil" or "--nocil"
///
/// The name of the flag. This is case sensitive.
/// True if set, or false if prefixed by "--no"
/// True if the flag was handled, or false otherwise.
bool handleFlag(string key, bool value);
///
/// Handle an argument, not prefixed by "--".
///
/// The command line argument.
/// True if the argument was handled, or false otherwise.
bool handleArgument(string argument);
///
/// Process an unhandled option, or an unhandled argument.
///
/// The argument.
void invalidArgument(string argument);
}
public static class OptionsExtensions
{
public static void ParseArguments(this ICommandLineOptions options, IReadOnlyList arguments)
{
for (int i = 0; i < arguments.Count; ++i)
{
string arg = arguments[i];
if (arg.StartsWith("--"))
{
var colon = arg.IndexOf(':');
if (colon > 0 && options.handleOption(arg.Substring(2, colon - 2), arg.Substring(colon + 1)))
{ }
else if (arg.StartsWith("--no") && options.handleFlag(arg.Substring(4), false))
{ }
else if (options.handleFlag(arg.Substring(2), true))
{ }
else if (i + 1 < arguments.Count && options.handleOption(arg.Substring(2), arguments[i + 1]))
{
++i;
}
else
{
options.invalidArgument(arg);
}
}
else
{
if (!options.handleArgument(arg))
{
options.invalidArgument(arg);
}
}
}
}
}
}