仿真平台内核初版 -tlib库 包含<sparc arm riscv powerPC>
This commit is contained in:
48
lib/options-parser/Help/ApplicationInfo.cs
Normal file
48
lib/options-parser/Help/ApplicationInfo.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Antmicro.OptionsParser
|
||||
{
|
||||
public class ApplicationInfo
|
||||
{
|
||||
public ApplicationInfo()
|
||||
{
|
||||
var entryAssembly = Assembly.GetEntryAssembly();
|
||||
|
||||
var applicationNameAttribute = entryAssembly?.GetCustomAttribute<AssemblyTitleAttribute>();
|
||||
if(applicationNameAttribute != null)
|
||||
{
|
||||
ApplicationName = applicationNameAttribute.Title;
|
||||
}
|
||||
|
||||
// assembly version is not available through custom attribute...
|
||||
ApplicationVersion = entryAssembly?.GetName().Version.ToString();
|
||||
|
||||
var applicationCopyrightAttribute = entryAssembly?.GetCustomAttribute<AssemblyCopyrightAttribute>();
|
||||
if(applicationCopyrightAttribute != null)
|
||||
{
|
||||
ApplicationCopyrights = applicationCopyrightAttribute.Copyright;
|
||||
}
|
||||
|
||||
ApplicationBinaryName = AppDomain.CurrentDomain.FriendlyName;
|
||||
|
||||
var metadataAttributes = entryAssembly?.GetCustomAttributes<AssemblyMetadataAttribute>();
|
||||
foreach(var attribute in metadataAttributes)
|
||||
{
|
||||
switch(attribute.Key)
|
||||
{
|
||||
case "BinaryName":
|
||||
ApplicationBinaryName = attribute.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ApplicationName { get; private set; }
|
||||
public string ApplicationBinaryName { get; private set; }
|
||||
public string ApplicationVersion { get; private set; }
|
||||
public string ApplicationCopyrights { get; private set; }
|
||||
}
|
||||
}
|
||||
|
||||
203
lib/options-parser/Help/HelpOption.cs
Normal file
203
lib/options-parser/Help/HelpOption.cs
Normal file
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
|
||||
namespace Antmicro.OptionsParser
|
||||
{
|
||||
public class HelpOption : CommandLineOptionDescriptor
|
||||
{
|
||||
public static HelpOption CreateInstance()
|
||||
{
|
||||
return new HelpOption(new ApplicationInfo());
|
||||
}
|
||||
|
||||
public void PrintHelp(OptionsParser parser)
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(appInfo.ApplicationName))
|
||||
{
|
||||
Console.Write(appInfo.ApplicationName);
|
||||
Console.WriteLine(string.IsNullOrWhiteSpace(appInfo.ApplicationVersion) ? string.Empty : " " + appInfo.ApplicationVersion);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(appInfo.ApplicationCopyrights))
|
||||
{
|
||||
Console.WriteLine(appInfo.ApplicationCopyrights);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
var valuesBuilder = new StringBuilder();
|
||||
foreach(var value in parser.Values)
|
||||
{
|
||||
if(value.IsRequired)
|
||||
{
|
||||
valuesBuilder.Append(' ').Append(value.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
valuesBuilder.AppendFormat(" [{0}]", value.Name);
|
||||
}
|
||||
}
|
||||
|
||||
var usageLine = string.Format(UsageLineFormat, appInfo.ApplicationBinaryName, valuesBuilder);
|
||||
Console.WriteLine(CustomUsageLineGenerator != null
|
||||
? CustomUsageLineGenerator(usageLine)
|
||||
: usageLine);
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
var interestingPositionalArguments = parser.Values.Where(x => !string.IsNullOrEmpty(x.Description) || x.ParameterType.IsEnum).ToList();
|
||||
if(interestingPositionalArguments.Count > 0)
|
||||
{
|
||||
Console.WriteLine("Arguments:");
|
||||
Console.WriteLine();
|
||||
|
||||
foreach(var value in interestingPositionalArguments)
|
||||
{
|
||||
Console.WriteLine(GeneratePositionalArgumentHelpEntry(value));
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine();
|
||||
|
||||
foreach(var option in parser.Options)
|
||||
{
|
||||
Console.WriteLine(GenerateOptionHelpEntry(option));
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
if(CustomFooterGenerator != null)
|
||||
{
|
||||
Console.WriteLine(CustomFooterGenerator());
|
||||
}
|
||||
}
|
||||
|
||||
public Func<IFlag, string> CustomOptionEntryHelpGenerator { get; set; }
|
||||
|
||||
public Func<string, string> CustomUsageLineGenerator { get; set; }
|
||||
|
||||
public Func<string> CustomFooterGenerator { get; set; }
|
||||
|
||||
public const string UsageLineFormat = "usage: {0} [options]{1}";
|
||||
|
||||
private static string GeneratePositionalArgumentHelpEntry(PositionalArgument argument)
|
||||
{
|
||||
var optionBuilder = new StringBuilder();
|
||||
optionBuilder.AppendFormat(" '{0}' has possible values:\n\n", argument.Name);
|
||||
|
||||
if(argument.ParameterType.IsEnum)
|
||||
{
|
||||
foreach(var e in GetEnumNames(argument.ParameterType))
|
||||
{
|
||||
optionBuilder.AppendFormat(" {0,-26}", e.Item1);
|
||||
if(e.Item2 != null)
|
||||
{
|
||||
optionBuilder.Append(e.Item2);
|
||||
}
|
||||
|
||||
optionBuilder.Append("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
return optionBuilder.ToString();
|
||||
}
|
||||
|
||||
private static string GenerateOptionHelpEntry(IFlag option)
|
||||
{
|
||||
var optionBuilder = new StringBuilder(" ");
|
||||
|
||||
AppendSwitchName(optionBuilder, option);
|
||||
optionBuilder.Append(' ', Math.Max(0, DefaultIndent - optionBuilder.Length));
|
||||
AppendTypeInformation(optionBuilder, option);
|
||||
|
||||
if(option.IsRequired)
|
||||
{
|
||||
optionBuilder.Append(" (required)");
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(option.Description))
|
||||
{
|
||||
optionBuilder.AppendLine();
|
||||
|
||||
optionBuilder.Append(' ', DefaultIndent);
|
||||
optionBuilder.Append(option.Description);
|
||||
}
|
||||
|
||||
foreach(var alias in option.Aliases)
|
||||
{
|
||||
optionBuilder.AppendLine().AppendLine();
|
||||
optionBuilder.AppendFormat(" --{0}", alias);
|
||||
optionBuilder.Append(' ', Math.Max(0, DefaultIndent - 4 - alias.Length)); // -4 to account for dashes and spaces
|
||||
AppendTypeInformation(optionBuilder, option);
|
||||
optionBuilder.AppendLine();
|
||||
|
||||
optionBuilder.Append(' ', DefaultIndent);
|
||||
optionBuilder.Append("Alias to ");
|
||||
AppendSwitchName(optionBuilder, option);
|
||||
optionBuilder.Append(".");
|
||||
}
|
||||
|
||||
return optionBuilder.ToString();
|
||||
}
|
||||
|
||||
private static void AppendSwitchName(StringBuilder optionBuilder, IFlag option)
|
||||
{
|
||||
if(option.ShortName != Tokenizer.NullCharacter)
|
||||
{
|
||||
optionBuilder.AppendFormat("-{0}", option.ShortName);
|
||||
}
|
||||
if(option.LongName != null)
|
||||
{
|
||||
if(option.ShortName != Tokenizer.NullCharacter)
|
||||
{
|
||||
optionBuilder.Append(", ");
|
||||
}
|
||||
|
||||
optionBuilder.AppendFormat("--{0}", option.LongName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AppendTypeInformation(StringBuilder optionBuilder, IFlag option)
|
||||
{
|
||||
if(option.OptionType.IsArray)
|
||||
{
|
||||
optionBuilder.AppendFormat("{0}s separated by '{1}'", option.OptionType.GetElementType().Name.ToUpper(), option.Delimiter);
|
||||
}
|
||||
else if(option.OptionType.IsEnum)
|
||||
{
|
||||
optionBuilder.AppendLine("ENUM with possible values: ");
|
||||
foreach(var name in GetEnumNames(option.OptionType))
|
||||
{
|
||||
optionBuilder.Append(' ', 32).Append(name.Item1).Append('\n');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
optionBuilder.Append(option.OptionType.Name.ToUpper());
|
||||
}
|
||||
}
|
||||
|
||||
private static Tuple<string, string>[] GetEnumNames(Type enumType)
|
||||
{
|
||||
DescriptionAttribute attr;
|
||||
|
||||
return Enum.GetValues(enumType)
|
||||
.Cast<Enum>()
|
||||
.Select(x => Enum.GetName(enumType, x))
|
||||
.Where(x => enumType.GetMember(x)[0].GetCustomAttribute<HideAttribute>() == null)
|
||||
.Select(x => Tuple.Create(x, (attr = enumType.GetMember(x)[0].GetCustomAttribute<DescriptionAttribute>()) != null ? attr.Value : null))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private HelpOption(ApplicationInfo info) : base('h', "help", typeof(bool))
|
||||
{
|
||||
Description = "Display this help page.";
|
||||
appInfo = info;
|
||||
}
|
||||
|
||||
private readonly ApplicationInfo appInfo;
|
||||
private const int DefaultIndent = 30;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user