/// <summary> Return the verb information of the given <paramref name="optionType"/>. </summary> private static VerbInfo GetVerb(Type optionType, VerbAttribute verb) { PropertyInfo[] optionPropertySet = optionType.GetProperties(); OptionInfo[] optionSet = new OptionInfo[optionPropertySet.Length]; int p = 0; for (int i = -1; ++i != optionPropertySet.Length;) { PropertyInfo property = optionPropertySet[i]; OptionAttribute optAttr = property.GetCustomAttribute <OptionAttribute>(); if (optAttr == null) { continue; } optionSet[p++] = new OptionInfo(property, optAttr); } Array.Resize(ref optionSet, p); return(new VerbInfo(optionType, verb, optionSet)); }
/// <summary> /// Returns the verb information of the given <paramref name="verb"/> that may /// match an element of the given <paramref name="optionTypes"/>. If no matching /// element is found, NULL is returned. /// </summary> private static VerbInfo GetVerb(string verb, Type[] optionTypes) { if (verb == null) { return(GetVerb(optionTypes[0], null)); } for (int i = -1; ++i != optionTypes.Length;) { Type optionType = optionTypes[i]; VerbAttribute verbAttr = optionType.GetCustomAttribute <VerbAttribute>(); if (verbAttr == null) { continue; } if (!string.Equals(verb, verbAttr.Name, StringComparison.InvariantCultureIgnoreCase)) { continue; } return(GetVerb(optionType, verbAttr)); } return(null); }
/// <summary> /// Writes the help (usage) information including the specified <paramref name="errorText"/> /// to the assigned <paramref name="stream"/> for the given set of <paramref name="optionTypes"/>. /// Note, the <paramref name="errorText"/> is only written when it's not NULL. /// Returns always FALSE for fluent signature. /// </summary> private static bool PrintUsageWithError(TextWriter stream, string errorText, Type[] optionTypes, VerbInfo verbNfo) { if (stream == null) { return(false); } const int padRight = 50; const string leftOffset = " "; const string midOffset = " "; Assembly myAssembly = Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly(); FileVersionInfo fileVersionNfo = FileVersionInfo.GetVersionInfo(myAssembly.Location); string name = fileVersionNfo.ProductName; string version = fileVersionNfo.ProductVersion; string copyright = fileVersionNfo.LegalCopyright; stream.WriteLine($"{name} {version}"); stream.WriteLine(copyright); stream.WriteLine(); if (!string.IsNullOrEmpty(errorText)) { stream.WriteLine("ERROR(S)"); stream.WriteLine($" {errorText}"); stream.WriteLine(); } stream.WriteLine("ARGUMENT(S)"); // No-verb mode? if (verbNfo == null && optionTypes.Length == 1) { verbNfo = GetVerb(optionTypes[0], null); } // Print verb information if (verbNfo == null) { int maxVerbNameChars = 0; VerbInfo[] verbSet = new VerbInfo[optionTypes.Length]; int p = 0; for (int i = -1; ++i != optionTypes.Length;) { Type optionType = optionTypes[i]; VerbAttribute verbAttr = optionType.GetCustomAttribute <VerbAttribute>(); if (verbAttr == null) { continue; } VerbInfo optVerbNfo = GetVerb(optionType, verbAttr); maxVerbNameChars = Math.Max(maxVerbNameChars, optVerbNfo.GetName().Length); verbSet[p++] = optVerbNfo; } Array.Resize(ref verbSet, p); for (int i = -1; ++i != p;) { VerbInfo verbOpt = verbSet[i]; string fullline = string.Concat( leftOffset, verbOpt.GetName().PadLeft(maxVerbNameChars), midOffset, verbOpt.GetHelpText().PadRight(padRight) ); stream.WriteLine(fullline); stream.WriteLine(); } stream.WriteLine("Unknown action. Check help!"); return(false); } // Print option information OptionInfo[] options = verbNfo.GetOptions(); string[] headlines = new string[options.Length]; string[] bodylines = new string[options.Length]; int maxOptionNameChars = 0; for (int i = -1; ++i != options.Length;) { OptionInfo option = options[i]; string shortName = option.GetShortName(); string fullName = option.GetFullName(); string required = option.IsRequired() ? "(Required) " : string.Empty; string deflt = option.GetDefaultValue() != null ? $"(Default {option.GetDefaultValue()}) " : string.Empty; string helpText = option.GetHelpText(); bool hasShortName = !string.IsNullOrEmpty(shortName); bool hasFullName = !string.IsNullOrEmpty(fullName); string headline = string.Empty; if (hasShortName) { headline = string.Concat(headline, "-", shortName); } if (hasShortName && hasFullName) { headline = string.Concat(headline, ", "); } if (hasFullName) { headline = string.Concat(headline, "--", fullName); } maxOptionNameChars = Math.Max(maxOptionNameChars, headline.Length); headlines[i] = headline; string bodyline = string.Concat(required, deflt, helpText); bodylines[i] = bodyline; } for (int i = -1; ++i != headlines.Length;) { string headline = headlines[i]; string bodyline = bodylines[i]; string fullline = string.Concat( leftOffset, headline.PadLeft(maxOptionNameChars), midOffset, bodyline.PadRight(padRight) ); stream.WriteLine(fullline); stream.WriteLine(); } stream.WriteLine("Missing arguments. Check help!"); return(false); }
/// <inheritdoc /> public VerbInfo(Type optionType, VerbAttribute attribute, OptionInfo[] options) { _optionType = optionType; _attribute = attribute; _options = options; }