/// <summary> /// Sets the value of a member property/field from the specified source dictionary. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="a"></param> /// <param name="context"></param> /// <param name="source"></param> private void SetMemberValue <T>(CommandLineParameterAttribute a, IObjectMemberContext context, IDictionary <string, T> source) { string[] keys = new string[] { a.Key, a.KeyShortForm ?? "" }; // T will be either bool or string, depending on whether source is "Switches" or "Named" foreach (string key in keys) { if (source.ContainsKey(key)) { T value = source[key]; if (context.MemberType == typeof(T)) { context.MemberValue = value; } else if (context.MemberType.IsEnum) { try { context.MemberValue = Enum.Parse(context.MemberType, value.ToString(), true); } catch (Exception) { throw new CommandLineException( string.Format("Invalid option for named command line argument: {0} ({1})", value, StringUtilities.Combine(keys, ", "))); } } else if (context.MemberType == typeof(int)) { context.MemberValue = int.Parse(value.ToString()); } return; } } if (a.Required) { throw new CommandLineException( string.Format("Missing required command line argument <{0}> ({1})", a.Usage, StringUtilities.Combine(keys, ", "))); } }
private void ProcessAttributes() { foreach (IObjectMemberContext context in WalkDataMembers()) { CommandLineParameterAttribute a = AttributeUtils.GetAttribute <CommandLineParameterAttribute>(context.Member); if (a != null) { if (a.Position > -1) { // treat as positional ValidateMemberType(context.Member.Name, new Type[] { typeof(string) }, context.MemberType); if (_positionalArgs.Count > a.Position) { context.MemberValue = _positionalArgs[a.Position]; } else { if (a.Required) { throw new CommandLineException(string.Format("Missing required command line argument <{0}>", a.DisplayName)); } } } else { // treat as named/switch if (context.MemberType == typeof(bool)) { ValidateMemberType(context.Member.Name, new Type[] { typeof(bool) }, context.MemberType); SetMemberValue(a, context, _switches); } else { ValidateMemberType(context.Member.Name, new Type[] { typeof(string), typeof(int), typeof(Enum) }, context.MemberType); SetMemberValue(a, context, _namedArgs); } } } } }
/// <summary> /// Generates a usage message, based on meta-data supplied by <see cref="CommandLineParameterAttribute"/>s declared /// on members of the subclass. /// </summary> /// <param name="writer"></param> public void PrintUsage(TextWriter writer) { List <string> positionals = new List <string>(); List <string> options = new List <string>(); foreach (IObjectMemberContext context in WalkDataMembers()) { CommandLineParameterAttribute a = AttributeUtils.GetAttribute <CommandLineParameterAttribute>(context.Member); if (a.Position > -1) { positionals.Add(string.Format(a.Required ? "{0}" : "[{0}]", a.DisplayName)); } else { string format = context.MemberType == typeof(bool) ? "/{0}[+|-]\t{1}" : "/{0}:(value)\t{1}"; string s = string.Format(format, a.Key, a.Usage); if (!string.IsNullOrEmpty(a.KeyShortForm)) { s += string.Format(" (Short form: /{0})", a.KeyShortForm); } options.Add(s); } } writer.Write("Usage: "); if (options.Count > 0) { writer.Write("[options] "); } positionals.ForEach(delegate(string s) { writer.Write("{0} ", s); }); writer.WriteLine(); if (options.Count > 0) { writer.WriteLine("Options:"); options.ForEach(delegate(string s) { writer.WriteLine(s); }); } }