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 (var i = 0; i < arguments.Count; ++i) { var 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); } } } } } }