Initial Commit
commit
b68568be3a
|
@ -0,0 +1,41 @@
|
|||
# Autosave files
|
||||
*~
|
||||
|
||||
# build
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
packages/
|
||||
TestResults/
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.DS_Store
|
||||
*.sln.cache
|
||||
*.suo
|
||||
*.cache
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.log
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.user
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
Thumbs.db
|
||||
.vs/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# resharper
|
||||
*_Resharper.*
|
||||
*.Resharper
|
||||
|
||||
# dotCover
|
||||
*.dotCover
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
|
||||
namespace ln.application
|
||||
{
|
||||
public class Argument : IArgument
|
||||
{
|
||||
public char OptionName { get; }
|
||||
public String LongOptionName { get; }
|
||||
public string HelpString { get; }
|
||||
|
||||
public bool HasArgument { get; set; }
|
||||
|
||||
public string Value { get; set; } = null;
|
||||
|
||||
public int IntegerValue => int.Parse(Value);
|
||||
public double DoubleValue => double.Parse(Value);
|
||||
|
||||
public Argument(char optionNameName, string longOptionNameName)
|
||||
{
|
||||
OptionName = optionNameName;
|
||||
LongOptionName = longOptionNameName;
|
||||
}
|
||||
public Argument(char optionNameName, string longOptionNameName, int defaultValue)
|
||||
: this(optionNameName, longOptionNameName, defaultValue.ToString()) { }
|
||||
public Argument(char optionNameName, string longOptionNameName, double defaultValue)
|
||||
: this(optionNameName, longOptionNameName, defaultValue.ToString()) { }
|
||||
|
||||
public Argument(char optionNameName, string longOptionNameName, string defaultValue)
|
||||
{
|
||||
OptionName = optionNameName;
|
||||
LongOptionName = longOptionNameName;
|
||||
Value = defaultValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ln.application
|
||||
{
|
||||
/// <summary>
|
||||
/// Argument container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class parses command line arguments to a list of predefined well known arguments.
|
||||
/// Remaining arguments will be found in <c>AdditionalArguments</c>.
|
||||
///
|
||||
/// <c>ArgumentContainer</c> also provides a global command line option:
|
||||
/// --change-static <para>typename</para> <para>fieldname</para> <para>value</para>
|
||||
/// It may be used multiple times on the command line.
|
||||
/// It will load the type referenced by the qualified name <para>typename</para> and try to set the static field <para>fieldname</para> to <para>value</para>.
|
||||
/// <para>value</para> will be casted to field type via Convert.ChangeType(...)
|
||||
/// </remarks>
|
||||
public class ArgumentContainer
|
||||
{
|
||||
private Dictionary<char, IArgument> shortOptionArguments = new Dictionary<char, IArgument>();
|
||||
private Dictionary<string, IArgument> longOptionArguments = new Dictionary<string, IArgument>();
|
||||
|
||||
public ArgumentContainer()
|
||||
{
|
||||
}
|
||||
public ArgumentContainer(IEnumerable<Argument> argumentDefinitions)
|
||||
{
|
||||
AddRange(argumentDefinitions);
|
||||
}
|
||||
|
||||
public ArgumentContainer(Type type)
|
||||
{
|
||||
AddStaticOptions(type);
|
||||
}
|
||||
|
||||
public IArgument this[string optionName] => longOptionArguments[optionName];
|
||||
public IArgument this[char option] => shortOptionArguments[option];
|
||||
|
||||
public bool Contains(string optionName) =>longOptionArguments.ContainsKey(optionName);
|
||||
public bool Contains(char option) => shortOptionArguments.ContainsKey(option);
|
||||
|
||||
public ArgumentContainer AddRange(IEnumerable<IArgument> arguments)
|
||||
{
|
||||
foreach (IArgument argument in arguments)
|
||||
Add(argument);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArgumentContainer Add(IArgument argument)
|
||||
{
|
||||
if (argument.OptionName > 0)
|
||||
shortOptionArguments.Add(argument.OptionName,argument);
|
||||
if (argument.LongOptionName != null)
|
||||
longOptionArguments.Add(argument.LongOptionName, argument);
|
||||
|
||||
return this;
|
||||
}
|
||||
public ArgumentContainer Add(char shortName) => Add(new Argument(shortName, null));
|
||||
public ArgumentContainer Add(string longName) => Add(new Argument((char)0, longName));
|
||||
public ArgumentContainer Add(char shortName, string longName) => Add(new Argument(shortName, longName));
|
||||
public ArgumentContainer Add(char shortName, string longName, string defaultValue) => Add(new Argument(shortName, longName, defaultValue));
|
||||
public ArgumentContainer Add(int shortName, string longName, string defaultValue) => Add(new Argument((char)shortName, longName, defaultValue));
|
||||
|
||||
public string[] Parse(IEnumerable<string> args)
|
||||
{
|
||||
List<string> unusedArguments = new List<string>();
|
||||
|
||||
Queue<string> q = new Queue<string>(args);
|
||||
while (q.Count > 0)
|
||||
{
|
||||
string currentOption = q.Dequeue();
|
||||
|
||||
if (currentOption[0].Equals('-'))
|
||||
{
|
||||
if (currentOption[1].Equals('-'))
|
||||
{
|
||||
String aname = currentOption.Substring(2);
|
||||
|
||||
if (aname.Equals("change-static"))
|
||||
{
|
||||
string typeName = q.Dequeue();
|
||||
string fieldName = q.Dequeue();
|
||||
string value = q.Dequeue();
|
||||
ChangeStatic(typeName, fieldName, value);
|
||||
}
|
||||
else if (Contains(aname))
|
||||
{
|
||||
IArgument argument = this[aname];
|
||||
argument.Value = argument.HasArgument ? q.Dequeue() : "";
|
||||
} else
|
||||
{
|
||||
unusedArguments.Add("--" + aname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (char option in currentOption.Substring(1))
|
||||
{
|
||||
IArgument argument = this[option];
|
||||
argument.Value = argument.HasArgument ? q.Dequeue() : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unusedArguments.Add(currentOption);
|
||||
}
|
||||
}
|
||||
|
||||
return unusedArguments.ToArray();
|
||||
}
|
||||
public void Parse(ref string[] args) => args = Parse(args);
|
||||
|
||||
public static string[] ApplyArguments<T>(string[] arguments)
|
||||
{
|
||||
ArgumentContainer argumentContainer = new ArgumentContainer();
|
||||
argumentContainer.AddStaticOptions(typeof(T));
|
||||
return argumentContainer.Parse(arguments);
|
||||
}
|
||||
public static void ApplyArguments<T>(ref string[] arguments)
|
||||
{
|
||||
arguments = ApplyArguments<T>(arguments);
|
||||
}
|
||||
|
||||
public static string[] ApplyArguments<T>(T instance,string[] arguments)
|
||||
{
|
||||
ArgumentContainer argumentContainer = new ArgumentContainer();
|
||||
argumentContainer.AddOptions(instance);
|
||||
return argumentContainer.Parse(arguments);
|
||||
}
|
||||
public static void ApplyArguments<T>(T instance,ref string[] arguments)
|
||||
{
|
||||
arguments = ApplyArguments(instance, arguments);
|
||||
}
|
||||
|
||||
public ArgumentContainer AddStaticOptions(Type type)
|
||||
{
|
||||
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
if (fieldInfo.GetCustomAttribute<StaticArgumentAttribute>() != null)
|
||||
Add(new FieldArgument(fieldInfo, fieldInfo.GetCustomAttribute<StaticArgumentAttribute>()));
|
||||
}
|
||||
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
if (propertyInfo.GetCustomAttribute<StaticArgumentAttribute>() != null)
|
||||
Add(new PropertyArgument(propertyInfo, propertyInfo.GetCustomAttribute<StaticArgumentAttribute>()));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
public ArgumentContainer AddOptions<T>(T instance)
|
||||
{
|
||||
foreach (FieldInfo fieldInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
if (fieldInfo.GetCustomAttribute<StaticArgumentAttribute>() != null)
|
||||
Add(new FieldArgument(instance, fieldInfo));
|
||||
}
|
||||
foreach (PropertyInfo propertyInfo in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
|
||||
{
|
||||
if (propertyInfo.GetCustomAttribute<StaticArgumentAttribute>() != null)
|
||||
Add(new PropertyArgument(instance, propertyInfo));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArgumentContainer AddStaticOptions<T>() => AddStaticOptions(typeof(T));
|
||||
|
||||
|
||||
public void ChangeStatic(string typeName,string fieldname,string value)
|
||||
{
|
||||
Type type = Type.GetType(typeName);
|
||||
FieldInfo fieldInfo = type.GetField(fieldname, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
object castValue = Convert.ChangeType(value, fieldInfo.FieldType);
|
||||
fieldInfo.SetValue(null,castValue);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using System.Reflection;
|
||||
using ln.type;
|
||||
|
||||
namespace ln.application
|
||||
{
|
||||
public class FieldArgument : IArgument
|
||||
{
|
||||
public FieldInfo FieldInfo { get; }
|
||||
public object Instance { get;}
|
||||
|
||||
public FieldArgument(FieldInfo fieldInfo)
|
||||
:this(null, fieldInfo, fieldInfo.GetCustomAttribute<StaticArgumentAttribute>())
|
||||
{}
|
||||
public FieldArgument(object instance,FieldInfo fieldInfo)
|
||||
:this(instance, fieldInfo, fieldInfo.GetCustomAttribute<StaticArgumentAttribute>())
|
||||
{}
|
||||
|
||||
public FieldArgument(FieldInfo fieldInfo, StaticArgumentAttribute staticArgumentAttribute)
|
||||
:this(null,fieldInfo,staticArgumentAttribute){}
|
||||
public FieldArgument(object instance,FieldInfo fieldInfo, StaticArgumentAttribute staticArgumentAttribute)
|
||||
{
|
||||
FieldInfo = fieldInfo;
|
||||
OptionName = staticArgumentAttribute?.Option ?? (char)0;
|
||||
LongOptionName = staticArgumentAttribute?.LongOption ?? fieldInfo.Name;
|
||||
HelpString = staticArgumentAttribute?.HelpString ?? "";
|
||||
HasArgument = fieldInfo.FieldType != typeof(bool);
|
||||
Instance = instance;
|
||||
}
|
||||
|
||||
public char OptionName { get; }
|
||||
public string LongOptionName { get; }
|
||||
public bool HasArgument { get; }
|
||||
public string HelpString { get; }
|
||||
public string Value
|
||||
{
|
||||
get => FieldInfo.GetValue(Instance)?.ToString();
|
||||
set
|
||||
{
|
||||
if (HasArgument)
|
||||
{
|
||||
FieldInfo.SetValue(Instance, Cast.To(value, FieldInfo.FieldType));
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldInfo.SetValue(Instance, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
namespace ln.application
|
||||
{
|
||||
public interface IArgument
|
||||
{
|
||||
char OptionName { get; }
|
||||
string LongOptionName { get; }
|
||||
|
||||
bool HasArgument { get; }
|
||||
|
||||
string HelpString { get; }
|
||||
|
||||
string Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using System.Reflection;
|
||||
using ln.type;
|
||||
|
||||
namespace ln.application
|
||||
{
|
||||
public class PropertyArgument : IArgument
|
||||
{
|
||||
public PropertyInfo PropertyInfo { get; }
|
||||
public object Instance { get;}
|
||||
|
||||
public PropertyArgument(PropertyInfo propertyInfo)
|
||||
:this(null, propertyInfo, propertyInfo.GetCustomAttribute<StaticArgumentAttribute>())
|
||||
{}
|
||||
public PropertyArgument(object instance, PropertyInfo propertyInfo)
|
||||
:this(instance, propertyInfo, propertyInfo.GetCustomAttribute<StaticArgumentAttribute>())
|
||||
{}
|
||||
|
||||
public PropertyArgument(PropertyInfo propertyInfo, StaticArgumentAttribute staticArgumentAttribute)
|
||||
:this(null, propertyInfo, staticArgumentAttribute){}
|
||||
public PropertyArgument(object instance,PropertyInfo propertyInfo, StaticArgumentAttribute staticArgumentAttribute)
|
||||
{
|
||||
PropertyInfo = propertyInfo;
|
||||
OptionName = staticArgumentAttribute?.Option ?? (char)0;
|
||||
LongOptionName = staticArgumentAttribute?.LongOption ?? propertyInfo.Name;
|
||||
HelpString = staticArgumentAttribute?.HelpString ?? "";
|
||||
HasArgument = propertyInfo.PropertyType != typeof(bool);
|
||||
Instance = instance;
|
||||
}
|
||||
|
||||
public char OptionName { get; }
|
||||
public string LongOptionName { get; }
|
||||
public bool HasArgument { get; }
|
||||
public string HelpString { get; }
|
||||
public string Value
|
||||
{
|
||||
get => PropertyInfo.GetValue(Instance)?.ToString();
|
||||
set
|
||||
{
|
||||
if (HasArgument)
|
||||
{
|
||||
PropertyInfo.SetValue(Instance, Cast.To(value, PropertyInfo.PropertyType));
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyInfo.SetValue(Instance, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace ln.application
|
||||
{
|
||||
public class StaticArgumentAttribute : Attribute
|
||||
{
|
||||
public char Option { get; set; }
|
||||
public string LongOption { get; set; }
|
||||
|
||||
public string HelpString { get; set; }
|
||||
|
||||
public StaticArgumentAttribute()
|
||||
{}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Version>0.1.0</Version>
|
||||
<Authors>Harald Wolff-Thobaben</Authors>
|
||||
<AssemblyVersion>0.0.1.0</AssemblyVersion>
|
||||
<FileVersion>0.0.1.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ln.type\ln.type.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Runtime" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue