/// <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();
                }
            }
        }
Beispiel #3
0
        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);
                }
            }
        }