/// <summary> /// Fills in the switchArguments and nonSwitchArguments data structures /// </summary> /// <param name="switchArguments">switch arguments - i.e. ones that have a -, --, or / in front, and their corresponding values</param> /// <param name="nonSwitchArguments">all non switch arguments</param> internal void Parse(Dictionary <string, List <string> > switchArguments, List <string> nonSwitchArguments) { bool parsing = true; while (this.currentIndex < this.args.Length) { try { string arg = this.args[this.currentIndex]; string orginalArg = arg; CommandLineArgumentType argumentType = this.GetCommandLineArgumentType(ref arg); if (argumentType == CommandLineArgumentType.EndSwitchMarker) { parsing = false; this.currentIndex++; continue; } List <string> valueList = new List <string>(); string value = string.Empty; if (parsing && argumentType == CommandLineArgumentType.Switch) { string[] keyValue = this.SplitIntoKeyAndValue(arg); string key = keyValue[0]; if (key.StartsWith(this.context.Settings.NoPrefix)) { key = key.Replace(this.context.Settings.NoPrefix, string.Empty); value = false.ToString(CultureInfo.CurrentCulture); } ArgumentDescriptor ar = this.context.GetDescriptor(key); if (ar == null || ar.IsHidden) { ++this.currentIndex; throw new CommandLineException(key, keyValue.Length > 1 ? keyValue[1] : string.Empty, "Unknown command line switch: " + key); } // if target is a bool then: // 1. if argument begins 'no-' it is always false, and should have no value // 2. if argument does not begin 'no-', and has a value separated by a defined separator, it takes that value // 3. it is true if (ar.MemberType == typeof(bool)) { if (string.IsNullOrWhiteSpace(value)) { // I am unclear about localization of string representations of bool: see http://stackoverflow.com/a/20620119 value = keyValue.Length > 1 ? keyValue[1] : true.ToString(CultureInfo.CurrentCulture); } else if (keyValue.Length > 1) { // this is a no-... switch, not allowed to have a value throw new CommandLineException(orginalArg, keyValue[1], "Value not allowed on a 'no-...' bool switch"); } } else { if (keyValue.Length > 1) { value = keyValue[1]; } else if (this.currentIndex + 1 < this.args.Length) { string v = this.args[this.currentIndex + 1]; if (!this.LooksLikeASwitch(v)) { value = v; ++this.currentIndex; } } } while (true) { valueList.Add(value); if (!ar.IsList || (this.currentIndex + 1 >= this.args.Length) || this.LooksLikeASwitch(this.args[this.currentIndex + 1])) { break; } value = this.args[++this.currentIndex]; } switchArguments[key] = valueList; } else { nonSwitchArguments.Add(arg); } ++this.currentIndex; } catch (Exception ex) { this.context.Exceptions.Add(ex); } } }
/// <summary> /// Adds a descriptor to the list of descriptors /// </summary> /// <param name="attributeData">The attribute data for the field or property</param> /// <param name="action">The action which sets the value</param> /// <param name="fieldName">The name of the field or property</param> /// <param name="targetType">The type of the field or property</param> private void AddDescriptor(CustomAttributeData attributeData, Action <object> action, string fieldName, Type targetType) { ArgumentDescriptor ar = new ArgumentDescriptor { Set = action, MemberType = targetType }; if (!this.context.Settings.RequireAttributes) { ar.MemberName = fieldName; } if (attributeData != null) { Debug.Assert(attributeData.ConstructorArguments.Count == 1, "Attribute constructor has incorrect number of parameters"); foreach (CustomAttributeTypedArgument constructorParameterName in attributeData.ConstructorArguments) { Debug.Assert(constructorParameterName.ArgumentType == typeof(string), "Attribute constructor parameter must be a string"); ar.Name = (string)constructorParameterName.Value; if (string.IsNullOrWhiteSpace(ar.Name)) { ar.IsHidden = true; } ar.MemberType = targetType; } if (attributeData.NamedArguments != null) { foreach (CustomAttributeNamedArgument optionalParameter in attributeData.NamedArguments) { if (optionalParameter.MemberName == "ShortName") { Debug.Assert(optionalParameter.TypedValue.ArgumentType == typeof(string), "Optional attribute parameter ShortName must be a string"); ar.ShortName = (string)optionalParameter.TypedValue.Value; } if (optionalParameter.MemberName == "Required") { Debug.Assert(optionalParameter.TypedValue.ArgumentType == typeof(bool), "Optional attribute parameter Required must be a bool"); ar.Required = (bool)optionalParameter.TypedValue.Value; } if (optionalParameter.MemberName == "HelpText") { Debug.Assert(optionalParameter.TypedValue.ArgumentType == typeof(string), "Optional attribute parameter Help must be a string"); ar.Help = (string)optionalParameter.TypedValue.Value; } } } } if (string.IsNullOrEmpty(ar.Name)) { ar.Name = ar.MemberName; } if ( this.context.Settings.CaseMatching == StringComparison.CurrentCultureIgnoreCase || this.context.Settings.CaseMatching == StringComparison.InvariantCultureIgnoreCase || this.context.Settings.CaseMatching == StringComparison.OrdinalIgnoreCase) { ar.Name = ar.Name.ToLower(CultureInfo.CurrentCulture); if (ar.ShortName != null) { ar.ShortName = ar.ShortName.ToLower(CultureInfo.CurrentCulture); } } ar.IsList = targetType.GetInterfaces() .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList <>)) != null; this.descriptors.Add(ar); }