Пример #1
0
        private static IEnumerable <Pattern> ParseLong(Tokens tokens, ICollection <Option> options)
        {
            // long ::= '--' chars [ ( ' ' | '=' ) chars ] ;
            var p        = new StringPartition(tokens.Move(), "=");
            var longName = p.LeftString;

            Debug.Assert(longName.StartsWith("--"));
            var value   = (p.NoSeparatorFound) ? null : new ValueObject(p.RightString);
            var similar = options.Where(o => o.LongName == longName).ToList();

            if (tokens.ThrowsInputError && similar.Count == 0)
            {
                // If not exact match
                similar =
                    options.Where(o => !string.IsNullOrEmpty(o.LongName) && o.LongName.StartsWith(longName)).ToList();
            }
            if (similar.Count > 1)
            {
                // Might be simply specified ambiguously 2+ times?
                throw tokens.CreateException($"{longName} is not a unique prefix: {string.Join(", ", similar.Select(o => o.LongName))}?");
            }
            Option option = null;

            if (similar.Count < 1)
            {
                var argCount = p.Separator == "=" ? 1 : 0;
                option = new Option(null, longName, argCount);
                options.Add(option);
                if (tokens.ThrowsInputError)
                {
                    option = new Option(null, longName, argCount, argCount != 0 ? value : new ValueObject(true));
                }
            }
            else
            {
                option = new Option(similar[0].ShortName, similar[0].LongName, similar[0].ArgCount, similar[0].Value);
                if (option.ArgCount == 0)
                {
                    if (value != null)
                    {
                        throw tokens.CreateException(option.LongName + " must not have an argument");
                    }
                }
                else
                {
                    if (value == null)
                    {
                        if (tokens.Current() == null || tokens.Current() == "--")
                        {
                            throw tokens.CreateException(option.LongName + " requires an argument");
                        }
                        value = new ValueObject(tokens.Move());
                    }
                }
                if (tokens.ThrowsInputError)
                {
                    option.Value = value ?? new ValueObject(true);
                }
            }
            return(new[] { option });
        }
Пример #2
0
        private static IEnumerable <Pattern> ParseShorts(Tokens tokens, ICollection <Option> options)
        {
            // shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ;

            var token = tokens.Move();

            Debug.Assert(token.StartsWith("-") && !token.StartsWith("--"));
            var left   = token.TrimStart('-');
            var parsed = new List <Pattern>();

            while (left != "")
            {
                var shortName = "-" + left[0];
                left = left.Substring(1);
                var    similar = options.Where(o => o.ShortName == shortName).ToList();
                Option option;

                if (similar.Count > 1)
                {
                    throw tokens.CreateException($"{shortName} is specified ambiguously {similar.Count} times");
                }

                if (similar.Count < 1)
                {
                    option = new Option(shortName);
                    options.Add(option);

                    if (tokens.ThrowsInputError)
                    {
                        option = new Option(shortName, null, 0, new ValueObject(true));
                    }
                }
                else
                {
                    // why is copying necessary here?
                    option = new Option(shortName, similar[0].LongName, similar[0].ArgCount, similar[0].Value);
                    ValueObject value = null;
                    if (option.ArgCount != 0)
                    {
                        if (left == "")
                        {
                            if (tokens.Current() == null || tokens.Current() == "--")
                            {
                                throw tokens.CreateException(shortName + " requires argument");
                            }

                            value = new ValueObject(tokens.Move());
                        }
                        else
                        {
                            value = new ValueObject(left);
                            left  = "";
                        }
                    }
                    if (tokens.ThrowsInputError)
                    {
                        option.Value = value ?? new ValueObject(true);
                    }
                }
                parsed.Add(option);
            }
            return(parsed);
        }