示例#1
0
        private ParsingResult WithResult(params ParsingResult[] Results)
        {
            var Merge = new ParsingResult()
            {
                Success = false
            };

            foreach (var item in Results)
            {
                Merge.FailResults.AddRange(item.FailResults);
            }

            return(Merge);
        }
示例#2
0
        private ParsingResult ProcessCommand(CommandDescriptor C, ref List <string> Param)
        {
            var CR = new ParsingResult()
            {
                Command = new CommandResult(C.CommandText)
            };

            string First = Skip(ref Param);

            int SwRequired = C.Switches.Where(f => f.Required).Count(),
                SwPossible = C.Switches.Count();

            int ArgRequired = C.Arguments.Where(f => f.Required).Count(),
                ArgPossible = C.Arguments.Count();

            int SubCommandFound = 0;

            while (!string.IsNullOrEmpty(First))
            {
                // if test command
                if (TestCommand(C.SubCommands, First))
                {
                    // extract and ..
                    var SC = GetCommand(C.SubCommands, First);

                    // process subcommand ..
                    var SCR = ProcessCommand(SC, ref Param);

                    if (SCR.Success)
                    {
                        // subcommand found ...
                        CR.Command.SubCommand = SCR.Command;
                        CR.Command.Switches.AddRange(SCR.Switches);

                        SubCommandFound++;
                    }
                    else
                    {
                        return(WithResult(CR, SCR));
                    }
                }
                else
                {
                    string Switch = First.Before(SwitchArgumentSeperator, First), SwitchValue = First.After(SwitchArgumentSeperator);
                    if (TestSwitch(C.Switches, Switch))
                    {
                        var SW  = GetSwitch(C.Switches, Switch);
                        var SWR = ProcessSwitch(C.Switches, ref Param);
                        if (SWR.Success)
                        {
                            CR.Command.Switches.AddRange(SWR.Switches);
                            if (SW.Required)
                            {
                                SwRequired--;
                            }

                            SwPossible--;
                        }
                        else
                        {
                            return(WithResult(CR, SWR));
                        }
                    }
                    else
                    {
                        if (C.SubCommands?.Length > 0)
                        {
                            return(WithResult(CR, "subcommand expected"));
                        }
                        try
                        {
                            var Arg = C.Arguments[CR.Command.Arguments.Count()];
                            CR.Command.Arguments.Add(new ArgumentResult(Arg.Argument, First));

                            if (Arg.Required)
                            {
                                ArgRequired--;
                            }

                            ArgPossible--;
                        }
                        catch
                        {
                            return(WithResult(CR, "position of argument could not specified"));
                        }
                    }
                }
                First = Skip(ref Param);
            }

            // final checks
            if (C.SubCommands?.Length > 0)
            {
                if (SubCommandFound == 0)
                {
                    return(WithResult(CR, "subcommand missing"));
                }
            }

            if (SwPossible < 0)
            {
                return(WithResult(CR, "too many switches"));
            }

            if (SwRequired > 0)
            {
                return(WithResult(CR, "required switch missing"));
            }

            if (ArgPossible < 0)
            {
                return(WithResult(CR, "too many arguments"));
            }

            if (ArgRequired > 0)
            {
                return(WithResult(CR, "required arguments missing"));
            }

            return(CR);
        }
示例#3
0
        public ParsingResult Parse(string Input)
        {
            var ParsingResult = new ParsingResult();

            // check empty
            if (string.IsNullOrWhiteSpace(Input))
            {
                return(WithResult(ParsingResult, "cli empty, nothing to do"));
            }

            // skip self, split and merge
            var Param        = Input.Split(' ').ToList();
            var ShrinkResult = ShrinkParams(Param);

            if (!ShrinkResult.Success)
            {
                return(WithResult(ParsingResult, ShrinkResult));
            }

            RemoveEmptyValues(ref Param);

            // parse common switches and remove them from param
            if (CliDefinition.Switches != null)
            {
                var ParseCommonSwitchResult = ParseCommonSwitches(CliDefinition.Switches, ref Param);
                if (ParseCommonSwitchResult.Success)
                {
                    ParsingResult.Switches.AddRange(ParseCommonSwitchResult.Switches);
                }
                else
                {
                    return(WithResult(ParsingResult, ParseCommonSwitchResult));
                }
            }


            if (Param.Count() == 0)
            {
                return(WithResult(ParsingResult, "nothing to do"));
            }

            // move through
            string First = Param.First(); //IEnumerable<string> Following = Param.Skip(1);

            // in command mode, first argument must be a command
            if (CliDefinition.Commands != null)
            {
                if (TestCommand(CliDefinition.Commands, First))
                {
                    var C  = GetCommand(CliDefinition.Commands, First);
                    var CR = ProcessCommand(C, ref Param);
                    if (CR.Success)
                    {
                        ParsingResult.Command = CR.Command;
                    }
                    else
                    {
                        return(WithResult(ParsingResult, CR));
                    }
                }
                else
                {
                    return(WithResult(ParsingResult, "first argument must be a command"));
                }
            }

            if (CliDefinition.Arguments != null)
            {
                // common switches already extracted .. only arguments remaining .. order required first ..
                var Arguments = CliDefinition.Arguments.OrderBy(f => f.Required ? 0 : 1)
                                .ThenBy(f => f.Position < 0 ? int.MaxValue : f.Position).ToArray();

                int ArgRequired = Arguments.Where(f => f.Required).Count(),
                    ArgPossible = Arguments.Count();

                for (int i = 0; i < Param.Count(); i++)
                {
                    ParsingResult.Arguments.Add(new ArgumentResult(Arguments[i].Argument, Param[i]));
                    if (Arguments[i].Required)
                    {
                        ArgRequired--;
                    }

                    ArgPossible--;
                }

                // final checks
                if (ArgPossible < 0)
                {
                    return(WithResult(ParsingResult, "too many arguments"));
                }

                if (ArgRequired > 0)
                {
                    return(WithResult(ParsingResult, "required argument missing"));
                }
            }
            ParsingResult.Success = true;
            return(ParsingResult);
        }
示例#4
0
        private ParsingResult ProcessSwitch(SwitchDescriptor[] S, ref List <string> Param)
        {
            var PR = new ParsingResult();

            int SwRequired = S.Where(f => f.Required).Count(),
                SwPossible = S.Count();

            string First = Param.First();
            string Switch = First.Before(SwitchArgumentSeperator, First), SwitchValue = First.After(SwitchArgumentSeperator);

            // get switch
            var Sw = GetSwitch(S, Switch);

            // and validate possible
            var SwitchValueResult = ValidateSwitchValue(Sw, SwitchValue);

            // if success
            if (SwitchValueResult.Success)
            {
                var SwitchArguments = new List <SwitchArgumentResult>();
                var SwResult        = new SwitchResult(Sw.SwitchText, Sw.ShortSwitch, Sw.SwitchValueType, SwitchValue);

                // remove switch ...
                //Param.RemoveAt(0);

                // check arguments .. switch arguments are always required
                for (int j = 0; j < Sw.SwitchArguments?.Length; j++)
                {
                    First = Skip(ref Param);
                    if (TestSwitch(S, First.Before(SwitchArgumentSeperator, First)))
                    {
                        return(WithResult(PR, "switch argument missing"));
                    }
                    else
                    {
                        SwitchArguments.Add(new SwitchArgumentResult(Sw.SwitchArguments[j].Argument, First));
                    }
                }
                SwResult.SwitchArguments.AddRange(SwitchArguments);

                // add to result ..
                if (Sw.Required)
                {
                    SwRequired--;
                }
                SwPossible--;

                PR.Switches.Add(SwResult);
            }
            else
            {
                return(WithResult(PR, SwitchValueResult));
            }

            //// final checks
            //if (SwPossible < 0)
            //    return WithResult(PR, "too many switches");

            //if (SwRequired > 0)
            //    return WithResult(PR, "required switch missing");

            return(PR);
        }