Пример #1
0
        /// <summary>
        /// Parse the indicated string table
        /// </summary>
        /// <param name="args"></param>
        public void Parse(string[] args)
        {
            //
            // This parser attempts to emulate, roughly, the behavior
            // of the POSIX getopt C runtime function for parsing
            // command line arguments.  This mechanism is fairly
            // easy to use as it is quite flexible in how it
            // lets you submit arguments for parsing.
            //
            // For example, all of these would be valid and equivalent
            // command line arguments if you had flags
            // p, q, and z where z takes an argument.
            //
            // -p -q -z7
            // -p -q -z 7
            // -pqz7
            // -p -qz7
            //
            // -p -qz "7"
            // -p -qz"7"
            //
            // The main difference between this parser and getopt, however,
            // is that with getopt you have to do command handling dispatch
            // yourself in a big switch statement.  This parser does
            // the dispatching automatically leveraging C#'s Action<> convention.
            //
            // This parser also provides a slightly more cumbersome syntax for
            // specifying arguments, but by paying this syntax tax, you get the
            // benefit of a help screen that can be generated automatically
            // for you based on the list of command arguments you supply to the
            // parser.  This reduces the common burden a writer of a command line
            // tool has.  It also ensures that the help screen for the application
            // is always up to date whenever new flags or arguments are added
            // to the tool.
            //

            //
            // reset the tracking collections for unknown and missing
            // required commands
            //
            ResetTrackingCollections();

            //
            // first, we merge the whole command line into a single string
            // since we're going to have to parse char by char
            //

            ///*******************************************************
            ///Update
            ///Update, by this way, we can use another args inputs
            ///var args = Environment.GetCommandLineArgs();


            //var joined = String.Join(" ", args.Skip(1).ToArray());

            //
            // we keep track of all commands dispatched to determine if
            // any commands that are required were not supplied
            //
            var dispatchedCommands = new List <CommandArgument>();

            //
            // these are the state variables that are used to track what's
            // going on in the command line as we walk character by character
            // through it.
            //
            bool            isLongArg      = false;
            CommandArgument currentCommand = null;

            //
            // now we walk through the characters of the array until
            // we determine if we've found a matching switch
            //
            foreach (String arg in args.Skip(1))
            {
                if (IsArgStart(arg))
                {
                    //
                    // we check if we're about to deal with a long argument
                    //
                    isLongArg = IsLongArg(arg);

                    String argName;

                    if (!isLongArg)
                    {
                        argName = arg.Substring(1, arg.Length - 1);
                    }
                    else
                    {
                        argName = arg.Substring(2, arg.Length - 2);
                    }
                    currentCommand = GetCommand(argName, isLongArg);

                    if (currentCommand != null)
                    {
                        //
                        // if the current command doesn't take a parameter,
                        // then we just dispatch it to it's handler
                        //
                        if (CommandArgumentFlags.FlagDisabled(currentCommand.Flags,
                                                              CommandArgumentFlags.TakesParameter))
                        {
                            dispatchedCommands.Add(currentCommand);
                            currentCommand = DispatchCommand(currentCommand, String.Empty);
                        }
                    }
                }
                else
                {
                    //
                    // if we've reached a new arg, but there is a current
                    // command, that means we've been gathering a parameter
                    // for it and it needs to be dispatched now.
                    //
                    if (currentCommand != null)
                    {
                        dispatchedCommands.Add(currentCommand);
                        currentCommand = DispatchCommand(currentCommand, arg);
                    }
                    else if ((currentCommand == null) && !String.IsNullOrEmpty(arg.Trim()))
                    {
                        this.unknownCommands.Add(arg);
                    }
                }
            }

            //
            // now that we're done with all the dispatching, we need to determine
            // if there were any required commands that didn't get supplied
            // and store that set for the caller to use
            //
            this.missingRequired = DetermineMissingRequiredCommands(dispatchedCommands);
        }
Пример #2
0
 private CommandArgument DispatchCommand(CommandArgument ca,
                                         string param)
 {
     ca.Action(this, param.Trim());
     return(null);
 }