/// <summary> /// Processes the commandline arguments. /// </summary> /// <param name="arguments">The arguments. If not specified (null) the Environment.GetCommandLineArgs() will be used</param> public void Parse(string[] arguments = null) { // Reset the tracking collections for unknown and missing required commands UnknownArguments.Clear(); MissingRequiredOptions.Clear(); DispatchedOptions.Clear(); // Clear the parser log; .NET framework 3.5 and below does not support the Clear() method! ParserLog.Length = 0; if (arguments == null) { arguments = Environment.GetCommandLineArgs().Skip(1).ToArray(); } // If debugging add the supplied arguments to the log if (DebugParser) { ParserLog.Append(string.Format("Arguments:")); foreach (string t in arguments) { ParserLog.Append(" " + t); } ParserLog.AppendLine(); } // Parse the arguments DoParse(arguments); // After dispatching all available commands, check if there were any required commands that didn't get supplied. MissingRequiredOptions = DetermineMissingRequiredOptions(DispatchedOptions); }
protected override void DoParse(string[] arguments) { StringBuilder sb = new StringBuilder(); foreach (string t in arguments) { sb.Append(" "); if (t.Contains(" ") && !(t.StartsWith("\"") && t.EndsWith("\""))) { sb.AppendFormat("\"{0}\"", t); } else { sb.Append(t); } } string allArguments = sb.ToString().Trim(); CommandlineParserState mode = CommandlineParserState.SearchCommandStart; int characterIndex = 0; int oldCharacterIndex = 0; string currentArgument = string.Empty; int paramSearchStartIndex = 0; bool longArg = false; CommandlineOption currentCommand = null; while (characterIndex < allArguments.Length) { switch (mode) { case CommandlineParserState.SearchCommandStart: if (IsOptionStart(allArguments, characterIndex)) { longArg = (IsLongOption(allArguments, characterIndex)); currentArgument = string.Empty; mode = CommandlineParserState.GetCommand; } else { currentArgument += allArguments[characterIndex]; } characterIndex++; if (longArg) { characterIndex++; } break; case CommandlineParserState.GetCommand: if (char.IsWhiteSpace(allArguments[characterIndex])) { mode = CommandlineParserState.SearchCommandStart; } currentArgument += allArguments[characterIndex]; currentCommand = GetArgument(currentArgument, longArg); if (currentCommand != null) { if (DebugParser) { ParserLog.AppendLine(string.Format("Command: {0}", currentArgument)); } currentArgument = string.Empty; if (currentCommand.Flags.HasAll(CommandlineOptionFlags.HasParameter)) { oldCharacterIndex = characterIndex + 1; mode = CommandlineParserState.SearchParameterStart; } else { DispatchedOptions.Add(currentCommand); DispatchOption(currentCommand, string.Empty); currentCommand = null; } } characterIndex++; break; case CommandlineParserState.SearchParameterStart: if (longArg) { if (char.IsWhiteSpace(allArguments[characterIndex])) { characterIndex++; } else { mode = CommandlineParserState.GetParameter; paramSearchStartIndex = characterIndex; } } else { if (!char.IsWhiteSpace(allArguments[characterIndex])) { currentArgument += allArguments[characterIndex]; characterIndex++; if (string.IsNullOrEmpty(currentArgument)) { mode = CommandlineParserState.SearchParameterStart; } if (GetArgument(currentArgument, false) != null) { currentArgument = string.Empty; } } else { while (characterIndex < allArguments.Length && char.IsWhiteSpace(allArguments[characterIndex])) { characterIndex++; } if (characterIndex < allArguments.Length) { mode = CommandlineParserState.GetParameter; paramSearchStartIndex = characterIndex; } else { mode = CommandlineParserState.SearchCommandStart; } } } break; case CommandlineParserState.GetParameter: if (!char.IsWhiteSpace(allArguments[characterIndex]) || currentArgument.StartsWith("\"", StringComparison.CurrentCulture)) { currentArgument += allArguments[characterIndex]; characterIndex++; if (characterIndex < allArguments.Length || (currentArgument.StartsWith("\"", StringComparison.CurrentCulture) && !currentArgument.EndsWith("\"", StringComparison.CurrentCulture))) { continue; } } if (DebugParser) { ParserLog.AppendLine(string.Format("Parameter: {0}", currentArgument)); } string param = currentArgument.StartsWith("\"") && currentArgument.EndsWith("\"") ? currentArgument.Substring(1, currentArgument.Length - 2) : currentArgument; DispatchedOptions.Add(currentCommand); DispatchOption(currentCommand, param); currentCommand = null; allArguments = allArguments.Remove(paramSearchStartIndex, currentArgument.Length).TrimEnd(); currentArgument = string.Empty; characterIndex = oldCharacterIndex; mode = CommandlineParserState.GetCommand; break; default: throw new ArgumentOutOfRangeException(); } } if (currentArgument != string.Empty) { switch (mode) { case CommandlineParserState.SearchCommandStart: case CommandlineParserState.GetCommand: if (DebugParser) { ParserLog.AppendLine(string.Format("Unkown Command: {0}", currentArgument)); } UnknownArguments.Add(currentArgument); break; case CommandlineParserState.GetParameter: if (DebugParser) { ParserLog.AppendLine(string.Format("Parameter (on exit): {0}", currentArgument)); } DispatchedOptions.Add(currentCommand); DispatchOption(currentCommand, currentArgument); break; default: throw new ArgumentOutOfRangeException(); } } }
protected override void DoParse(string[] arguments) { SortOptionsByRequiredPostion(); // First process all options that have required positions foreach (CommandlineOption currentOption in Options.Where(currentCommand => currentCommand.RequiredPosition != int.MaxValue && currentCommand.RequiredPosition < arguments.Length)) { if (DebugParser) { ParserLog.AppendLine(string.Format("Dispatching {0}; value {1}", currentOption.Name, arguments[currentOption.RequiredPosition])); } string arg = arguments[currentOption.RequiredPosition]; if (string.IsNullOrEmpty(arg) || IsOptionStart(arg, 0)) { continue; } // Dispatch option and mark argument handled (null) DispatchedOptions.Add(currentOption); DispatchOption(currentOption, arguments[currentOption.RequiredPosition]); arguments[currentOption.RequiredPosition] = null; } // Process the all other (not null) arguments foreach (string currentArgument in arguments.Where(currentArgument => !string.IsNullOrEmpty(currentArgument))) { // Option should start with an OptionPrefixes character if (!IsOptionStart(currentArgument, 0)) { if (DebugParser) { ParserLog.AppendLine(string.Format("{0}: No option start found", currentArgument)); } UnknownArguments.Add(currentArgument); continue; } // Split current argument in a command and a parameter string string parameter = string.Empty; string command = currentArgument.Substring(1); int index = command.IndexOfAny(ArgumentValueSeperator); if (index > 0) { parameter = command.Substring(index + 1); command = command.Substring(0, index); } if (DebugParser) { ParserLog.AppendLine(string.Format("Option: {0}, Parameter: {1}", command, parameter)); } // Find the option handling the current command string CommandlineOption currentOption = GetArgument(command, true, StringComparison.InvariantCultureIgnoreCase) ?? GetArgument(command, false, StringComparison.InvariantCultureIgnoreCase); if (currentOption != null) { // If option found check if the parameter is required if (currentOption.Flags.HasAny(CommandlineOptionFlags.HasParameter) && string.IsNullOrEmpty(parameter)) { if (DebugParser) { ParserLog.AppendLine(string.Format("{0}: Missing required parameter.", currentOption.Name)); } UnknownArguments.Add(string.Format("{0}: Missing required parameter.", command)); } else { // Dispatch the option if (DebugParser) { ParserLog.AppendLine(string.Format("Dispatching {0}; value {1}", currentOption.Name, parameter)); } DispatchedOptions.Add(currentOption); DispatchOption(currentOption, parameter); } } else { // Invalid option if (DebugParser) { ParserLog.AppendLine(string.Format("Invalid argument: {0}", command)); } UnknownArguments.Add(command); } } }