예제 #1
0
파일: FlagSet.cs 프로젝트: mikeruhl/goflag
        /// <summary>
        /// Sets the value of the named flag.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <exception cref="ArgumentException">Thrown when name does not exist as flag or when string value cannot be converted to desired type.</exception>
        public void Set(string name, string value)
        {
            var flagExists = Formal.TryGetValue(name, out var flag);

            if (!flagExists)
            {
                throw new ArgumentException("No such flag", nameof(name));
            }

            if (!flag.TrySetValue(value, out var err))
            {
                throw new ArgumentException($"Could not set value: {err}", nameof(value));
            }

            if (Actual == null)
            {
                Actual = new Dictionary <string, IFlag>();
            }

            if (Actual.ContainsKey(name))
            {
                Actual[name] = flag;
            }
            else
            {
                Actual.Add(name, flag);
            }
        }
예제 #2
0
파일: FlagSet.cs 프로젝트: mikeruhl/goflag
        internal (bool, ParsingError) ParseOne()
        {
            if (Args.Length == 0)
            {
                return(false, null);
            }
            var s = Args[0];

            if (s.Length < 2 || s[0] != '-')
            {
                return(false, null);
            }
            var numMinuses = 1;

            if (s[1] == '-')
            {
                numMinuses++;
                if (s.Length == 2) // "--" terminates the flags
                {
                    Args = Args.Skip(1).ToArray();
                    return(false, null);
                }
            }
            var name = s.Substring(numMinuses);

            if (name.Length == 0 || name[0] == '-' || name[0] == '=')
            {
                return(false, FailF($"bad flag syntax: {0}", s));
            }

            //it's a flag, does it have an argument?
            Args = Args.Skip(1).ToArray();
            var hasValue = false;
            var value    = "";

            for (var i = 1; i < name.Length; i++)
            {
                if (name[i] == '=')
                {
                    value    = name.Substring(i + 1);
                    hasValue = true;
                    name     = name.Substring(0, i);
                }
            }
            IFlag flag         = null;
            var   alreadyThere = Formal != null && Formal.TryGetValue(name, out flag);

            if (!alreadyThere)
            {
                if (name.Equals("help", StringComparison.CurrentCultureIgnoreCase) ||
                    name.Equals("h", StringComparison.CurrentCultureIgnoreCase))
                {
                    Usage();
                    return(false, ErrHelp);
                }
                return(false, FailF("flag provided but not defined: -{0}", name));
            }

            if (flag?.TrackedType == typeof(bool)) //special case, doesn't need an arg
            {
                if (hasValue)
                {
                    if (!flag.TrySetValue(value, out var err))
                    {
                        if (value.Equals("0") && !flag.TrySetValue("false", out err)) //account for 0 and 1 values (inherint in Go, not in C#)
                        {
                            return(false, FailF("invalid boolean value \"{0}\" for -{1}: {2}", value, name, err));
                        }
                        else if (value.Equals("1") && !flag.TrySetValue("true", out err))
                        {
                            return(false, FailF("invalid boolean value \"{0}\" for -{1}: {2}", value, name, err));
                        }
                        else
                        {
                            return(false, FailF("invalid boolean value \"{0}\" for -{1}: {2}", value, name, err));
                        }
                    }
                }
                else
                {
                    if (!flag.TrySetValue("true", out var err))
                    {
                        return(false, FailF("invalid boolean flag {0}: {1}", name, err));
                    }
                }
            }
            else
            {
                //It must have a value, which might be the next argument.
                if (!hasValue && Args.Length > 0)
                {
                    //value is the next arg
                    hasValue = true;
                    value    = Args[0];
                    Args     = Args.Skip(1).ToArray();
                }
                if (!hasValue)
                {
                    return(false, FailF("flag needs an argument: -{0}", name));
                }
                if (!flag.TrySetValue(value, out var err))
                {
                    return(false, FailF("invalid value \"{0}\" for flag -{1}: {2}", value, name, err));
                }
            }
            if (Actual == null)
            {
                Actual = new Dictionary <string, IFlag>();
            }

            if (Actual.ContainsKey(name))
            {
                Actual[name] = flag;
            }
            else
            {
                Actual.Add(name, flag);
            }

            return(true, null);
        }