public override MatchResult Match(IList<Pattern> left, IEnumerable<Pattern> collected = null)
 {
     var coll = collected ?? new List<Pattern>();
     var sresult = SingleMatch(left);
     var match = sresult.Match;
     if (match == null)
     {
         return new MatchResult(false, left, coll);
     }
     var left_ = new List<Pattern>();
     left_.AddRange(left.Take(sresult.Position));
     left_.AddRange(left.Skip(sresult.Position + 1));
     var sameName = coll.Where(a => a.Name == Name).ToList();
     if (Value != null && (Value.IsList || Value.IsOfTypeInt))
     {
         var increment = new ValueObject(1);
         if (!Value.IsOfTypeInt)
         {
             increment = match.Value.IsString ? new ValueObject(new [] {match.Value})  : match.Value;
         }
         if (sameName.Count == 0) 
         {
             match.Value = increment;
             var res = new List<Pattern>(coll) {match};
             return new MatchResult(true, left_, res);
         }
         sameName[0].Value.Add(increment);
         return new MatchResult(true, left_, coll);
     }
     var resColl = new List<Pattern>();
     resColl.AddRange(coll);
     resColl.Add(match);
     return new MatchResult(true, left_, resColl);
 }
Beispiel #2
0
        public static Option Parse(string optionDescription)
        {
            if (optionDescription == null) throw new ArgumentNullException("optionDescription");

            string shortName = null;
            string longName = null;
            var argCount = 0;
            var value = new ValueObject(false);
            var p = new StringPartition(optionDescription, DESC_SEPARATOR);
            var options = p.LeftString;
            var description = p.RightString;
            foreach (var s in options.Split(" \t,=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (s.StartsWith("--"))
                    longName = s;
                else if (s.StartsWith("-"))
                {
                    shortName = s;
                }
                else
                {
                    argCount = 1;
                }
            }
            if (argCount > 0)
            {
                var r = new Regex(@"\[default: (.*)\]", RegexOptions.IgnoreCase);
                var m = r.Match(description);
                value = m.Success ? new ValueObject(m.Groups[1].Value) : null;
            }
            return new Option(shortName, longName, argCount, value);
        }
Beispiel #3
0
 public Option(string shortName = null, string longName = null, int argCount = 0, ValueObject value = null)
     : base()
 {
     ShortName = shortName;
     LongName = longName;
     ArgCount = argCount;
     var v = value ?? new ValueObject(false);
     Value = (v.IsFalse && argCount > 0) ? null : v;
 }
Beispiel #4
0
 public Argument(string name, ValueObject value = null) : base(name, value)
 {
 }
Beispiel #5
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(string.Format("{0} is not a unique prefix: {1}?", longName,
                                                    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};
 }
Beispiel #6
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(new[] {'-'});
            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 = null;
                if (similar.Count > 1)
                {
                    throw tokens.CreateException(string.Format("{0} is specified ambiguously {1} times", shortName,
                                                               similar.Count));
                }
                if (similar.Count < 1)
                {
                    option = new Option(shortName, null, 0);
                    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;
        }
Beispiel #7
0
 public Command(string name, ValueObject value = null) : base(name, value ?? new ValueObject(false))
 {
 }
 protected LeafPattern(string name, ValueObject value=null)
 {
     _name = name;
     Value = value;
 }
Beispiel #9
0
 static string Normalize(ValueObject v)
 {
     if (v == null) return null;
     var s = v.ToString();
     return string.IsNullOrWhiteSpace(s) ? null : s;
 }
        public void Add(ValueObject increment)
        {
            if (increment == null) throw new ArgumentNullException("increment");

            if (increment.Value == null) throw new InvalidOperationException("increment.Value is null");

            if (Value == null) throw new InvalidOperationException("Value is null");

            if (increment.IsInt)
            {
                if (IsList)
                    (Value as ArrayList).Add(increment.AsInt);
                else
                    Value = increment.AsInt + AsInt;
            }
            else
            {
                var l = new ArrayList();
                if (IsList)
                {
                    l.AddRange(AsList);
                }
                else
                {
                    l.Add(Value);
                }
                if (increment.IsList)
                {
                    l.AddRange(increment.AsList);
                }
                else
                {
                    l.Add(increment);
                }
                Value = l;
            }
        }
Beispiel #11
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 });
        }
Beispiel #12
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);
        }
Beispiel #13
0
        public Option(string shortName = null, string longName = null, int argCount = 0, ValueObject value = null)
            : base()
        {
            ShortName = shortName;
            LongName  = longName;
            ArgCount  = argCount;
            var v = value ?? new ValueObject(false);

            Value = (v.IsFalse && argCount > 0) ? null : v;
        }