예제 #1
0
        /// <summary>
        /// Parse given arguments.
        /// </summary>
        /// <param name="args">The arguments to parse.</param>
        /// <returns>Remaining arguments.</returns>
        public string[] Parse(string[] args)
        {
            List <string> remainingArgs = new List <string>();
            bool          lastSwitch    = false;

            for (int i = 0; i < args.Length;)
            {
                if (lastSwitch)
                {
                    remainingArgs.Add(args[i++]);
                }
                else
                {
                    CommandLineSwitch clSwitch = GetBestMatch(args, i);
                    if (clSwitch == null)
                    {
                        remainingArgs.Add(args[i++]);
                    }
                    else if (clSwitch.ParsedArgsCount == 0)
                    {
                        throw new CommandLineSwitchSyntaxException(args[i++]);
                    }
                    else
                    {
                        i         += clSwitch.Commit();
                        lastSwitch = lastSwitch || clSwitch.EndMarkerSwitch;
                        if (clSwitch.RemainingArg.Length > 0)
                        {
                            remainingArgs.Add(clSwitch.RemainingArg);
                        }
                    }
                }
            }
            return(remainingArgs.ToArray());
        }
예제 #2
0
        /// <summary>
        /// Get the switch that best matches given arguments.
        /// </summary>
        /// <param name="args">The arguments array to parse.</param>
        /// <param name="startIndex">The index into the <paramref name="args"/> array where to start parsing.</param>
        /// <returns>The <see cref="CommandLineSwitch"/> that best matches given arguments</returns>
        public CommandLineSwitch GetBestMatch(string[] args, int startIndex)
        {
            CommandLineSwitch bestMatchSwitch = null;

            foreach (CommandLineSwitch item in SwitchesOrderedByType)
            {
                item.Parse(args, startIndex);
                if (item.ParsedLength == 0)
                {
                    if (item.EndMarkerSwitch)
                    {
                        return(item);
                    }
                    continue;
                }
                if (bestMatchSwitch == null ||
                    item.ParsedLength > bestMatchSwitch.ParsedLength ||
                    item.ParsedLength == bestMatchSwitch.ParsedLength && item.NameMatchExactly && !bestMatchSwitch.NameMatchExactly)
                {
                    bestMatchSwitch = item;
                }
                else if (item.NameMatchExactly == bestMatchSwitch.NameMatchExactly && item.ParsedLength == bestMatchSwitch.ParsedLength)
                {
                    throw new CommandLineSwitchAmbiguousException(item.ParsedName, new string[] { item.Name, bestMatchSwitch.Name });
                }
            }
            return(bestMatchSwitch);
        }
예제 #3
0
 /// <summary>
 /// Add command line switches for given <paramref name="objectWithSwitchAttributes"/> type.
 /// </summary>
 /// <param name="objectWithSwitchAttributes">The attributed object from which the switches will be created</param>
 public void AddSwitchesForType(object objectWithSwitchAttributes)
 {
     foreach (CommandLineSwitch item in CommandLineSwitch.CreateSwitchesForType(objectWithSwitchAttributes))
     {
         _switches[item.Name] = item;
     }
 }
예제 #4
0
        internal static IEnumerable <CommandLineSwitch> CreateSwitchesForType(object objectWithSwitchAttributes)
        {
            Type type = objectWithSwitchAttributes.GetType();

            MemberInfo[] members = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.SetProperty);
            for (int i = 0; i < members.Length; ++i)
            {
                object[] attributes = members[i].GetCustomAttributes(false);
                if (attributes.Length > 0)
                {
                    CommandLineSwitch clSwitch = null;
                    foreach (Attribute attribute in attributes)
                    {
                        if (attribute is CommandLineSwitchAttribute)
                        {
                            CommandLineSwitchAttribute switchAttribute = attribute as CommandLineSwitchAttribute;
                            // Get the property information.  We're only handling properties at the moment!
                            if (members[i] is PropertyInfo)
                            {
                                PropertyInfo pi         = (PropertyInfo)members[i];
                                string       switchName = switchAttribute.Name;
                                if (switchName == null || switchName.Length == 0)
                                {
                                    switchName = pi.Name;
                                }
                                clSwitch = CommandLineSwitch.Create(switchName, switchAttribute.Description, pi.PropertyType);
                                // Map in the Get/Set methods.
                                clSwitch.SetMethod = pi.GetSetMethod(true);
                                clSwitch.GetMethod = pi.GetGetMethod(true);
                                clSwitch.Target    = objectWithSwitchAttributes;
                                // Can only handle a single switch for each property
                                // (otherwise the parsing of aliases gets silly...)
                                break;
                            }
                        }
                    }
                    // See if any aliases are required.  We can only do this after
                    // a switch has been registered and the framework doesn't make
                    // any guarantees about the order of attributes, so we have to
                    // walk the collection a second time.
                    if (clSwitch != null)
                    {
                        foreach (Attribute attribute in attributes)
                        {
                            if (attribute is CommandLineSwitchAliasAttribute)
                            {
                                CommandLineSwitchAliasAttribute aliasAttribute = attribute as CommandLineSwitchAliasAttribute;
                                clSwitch.AddAlias(aliasAttribute.Alias);
                            }
                        }
                    }
                    // Assuming we have an switch (that may or may not have aliases), add it to the collection of switches.
                    if (clSwitch != null)
                    {
                        yield return(clSwitch);
                    }
                }
            }
        }