private static void ValidateRequiredValue(CmdArgAttribute caa, Boolean switchIncludesAValue, String name) { if ((caa.RequiredValue == CmdArgRequiredValue.Yes) && !switchIncludesAValue) { throw new Exception <InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), String.Format(CultureInfo.CurrentCulture, "The {0} switch requires an argument and none was specified.", name)); } if ((caa.RequiredValue == CmdArgRequiredValue.No) && switchIncludesAValue) { throw new Exception <InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), String.Format(CultureInfo.CurrentCulture, "The {0} switch cannot have an argument and one was specified.", name)); } }
private static IList <String> ValidateMembers(Type optionType) { List <String> argNames = new List <String>(); List <String> requiredArgNames = new List <String>(); const BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public; foreach (MemberInfo mi in optionType.GetMembers(bf)) { CmdArgAttribute caa = (CmdArgAttribute) Attribute.GetCustomAttribute(mi, typeof(CmdArgAttribute), false); // If the member doesn't have a CmdArgAttribute applied to it, try the next member if (caa == null) { continue; } // If no attribute-given name specified, use the member's name String argName = (caa.ArgName != null) ? caa.ArgName : mi.Name; // If this switch name was already defined, throw an exception if (argNames.Contains(argName)) { throw new Exception <CmdArgumentTypeExceptionArgs>( String.Format(CultureInfo.CurrentCulture, "The {0} switch appears more than once in the {1} class.", argName, optionType)); } // The switch name didn't exist, let's add it and try the next one argNames.Add(argName); // If this switch is required, let's add it to the set of required switches if (caa.RequiredArg) { requiredArgNames.Add(argName); } } // No switch name conflicts occurred, return the set of required switches return(requiredArgNames); }
private static MemberInfo LookupMember(Type optionType, String name, Boolean switchIncludesAValue, out CmdArgAttribute caa) { BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public; foreach (MemberInfo mi in optionType.GetMembers(bf)) { caa = (CmdArgAttribute) Attribute.GetCustomAttribute(mi, typeof(CmdArgAttribute), false); // If the member doesn't have a CmdArgAttribute applied to it, try the next member if (caa == null) continue; // If no attribute-given name specified, use the member's name String memberName = (caa.ArgName != null) ? caa.ArgName : mi.Name; // If the switch name matches the member's name, return the matching member if (String.Compare(name, memberName, StringComparison.OrdinalIgnoreCase) == 0) { ValidateRequiredValue(caa, switchIncludesAValue, name); return mi; } // If no match, try the next member } // If no members match, we have an invalid argument throw new Exception<InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), null); }
private static void ValidateRequiredValue(CmdArgAttribute caa, Boolean switchIncludesAValue, String name) { if ((caa.RequiredValue == CmdArgRequiredValue.Yes) && !switchIncludesAValue) { throw new Exception<InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), String.Format(CultureInfo.CurrentCulture, "The {0} switch requires an argument and none was specified.", name)); } if ((caa.RequiredValue == CmdArgRequiredValue.No) && switchIncludesAValue) { throw new Exception<InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), String.Format(CultureInfo.CurrentCulture, "The {0} switch cannot have an argument and one was specified.", name)); } }
/// <summary> /// Returns a string indicating the valid command-line arguments. /// </summary> /// <param name="optionType">The type adorned with custom /// attributes that indicate the valid command-line arguments.</param> /// <returns>A string indicating the valid command-line arguments.</returns> public static String Usage(Type optionType) { Contract.Requires(optionType != null); StringBuilder cmdLine = new StringBuilder(); cmdLine.AppendFormat("{0} ", Path.GetFileNameWithoutExtension( Assembly.GetEntryAssembly().Location)); const BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public; Int32 optionsAppended = 0; Dictionary <String, String> argAndDesc = new Dictionary <String, String>(); foreach (MemberInfo mi in optionType.GetMembers(bf)) { CmdArgAttribute caa = (CmdArgAttribute) Attribute.GetCustomAttribute(mi, typeof(CmdArgAttribute), false); // If the member doesn't have a CmdArgAttribute applied to it, try the next member if (caa == null) { continue; } // If the attribute indicates the argument is undocumented, try the next member if (caa.UndocumentedArg) { continue; } // Append the argument to the string: if (optionsAppended > 0) { cmdLine.Append(" "); } optionsAppended++; // If no attribute-given name specified, use the member's name String argName = (caa.ArgName != null) ? caa.ArgName : mi.Name; argAndDesc.Add(argName, caa.Description); // If the switch isn't required, it's optional: put it in square brackets if (!caa.RequiredArg) { cmdLine.Append("["); } cmdLine.AppendFormat("-{0}", argName); if (caa.RequiredValue == CmdArgRequiredValue.No) { // This switch must NOT have a value, the switch's type must be Boolean } else { // This switch MAY have a value, the switch's type doesn't have to be Boolean if (caa.RequiredValue == CmdArgRequiredValue.Optional) { cmdLine.Append("["); } cmdLine.Append(":"); Type switchType = GetFieldOrPropertyMemberType(mi); if (typeof(Enum).IsAssignableFrom(switchType)) { Array a = Enum.GetValues(switchType); for (Int32 n = 0; n < a.Length; n++) { cmdLine.AppendFormat("{0}{1}", (n > 0) ? "|" : "", a.GetValue(n)); CmdArgEnumValueDescriptionAttribute caevda = (CmdArgEnumValueDescriptionAttribute) Attribute.GetCustomAttribute(switchType.GetField(a.GetValue(n).ToString()), typeof(CmdArgEnumValueDescriptionAttribute), false); argAndDesc.Add(String.Format(CultureInfo.CurrentCulture, "{0}:{1}", argName, a.GetValue(n)), (caevda == null) ? "" : caevda.Description); } } else { cmdLine.Append(switchType.Name); } if (caa.RequiredValue == CmdArgRequiredValue.Optional) { cmdLine.Append("]"); } } if (!caa.RequiredArg) { cmdLine.Append("]"); } } cmdLine.AppendLine(); cmdLine.AppendLine(); Int32 longestArgName = 0; foreach (KeyValuePair <String, String> kv in argAndDesc) { longestArgName = Math.Max(longestArgName, kv.Key.Length); } foreach (KeyValuePair <String, String> kv in argAndDesc) { cmdLine.AppendFormat("-{0} ", kv.Key.PadRight(longestArgName)); String[] lines = BreakStringIntoLinesOfSpecifiedWidth(kv.Value, /*Console.WindowWidth*/ 80 - longestArgName - 3 - 1); for (Int32 line = 0; line < lines.Length; line++) { if (line == 0) { cmdLine.AppendFormat(CultureInfo.CurrentCulture, lines[line]); } else { cmdLine.AppendFormat(CultureInfo.CurrentCulture, "{0}{1}", new String(' ', 1 + longestArgName + 2), lines[line]); } cmdLine.AppendLine(); } } return(cmdLine.ToString()); }
private static MemberInfo LookupMember(Type optionType, String name, Boolean switchIncludesAValue, out CmdArgAttribute caa) { BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public; foreach (MemberInfo mi in optionType.GetMembers(bf)) { caa = (CmdArgAttribute)Attribute.GetCustomAttribute(mi, typeof(CmdArgAttribute), false); // If the member doesn't have a CmdArgAttribute applied to it, try the next member if (caa == null) { continue; } // If no attribute-given name specified, use the member's name String memberName = (caa.ArgName != null) ? caa.ArgName : mi.Name; // If the switch name matches the member's name, return the matching member if (String.Compare(name, memberName, StringComparison.OrdinalIgnoreCase) == 0) { ValidateRequiredValue(caa, switchIncludesAValue, name); return(mi); } // If no match, try the next member } // If no members match, we have an invalid argument throw new Exception <InvalidCmdArgumentExceptionArgs>( new InvalidCmdArgumentExceptionArgs(name), null); }