Improvements ( ArgumentReader, Option, Array.IndexOf() )

master
Harald Wolff 2017-12-07 20:19:43 +01:00
parent f07cc5b906
commit c9385cb467
6 changed files with 329 additions and 38 deletions

View File

@ -1,37 +0,0 @@
using System;
namespace sharp.extensions
{
public class ArgumentReader
{
int current;
string[] arguments;
public ArgumentReader(String[] arguments)
{
this.arguments = arguments;
this.current = 0;
}
public String Current { get { return this.arguments[this.current]; } }
public String Next() { MoveNext(); return Current; }
public bool MoveNext(){
this.current++;
return this.current < this.arguments.Length;
}
public string[] NextFollowing(int n)
{
string[] result = this.arguments.Segment(this.current + 1, n);
this.current += result.Length;
return result;
return new string[0];
}
public string[] Reminder(){
return this.arguments.Segment(this.current+1);
}
}
}

View File

@ -102,5 +102,14 @@ namespace sharp.extensions
return rl.ToArray();
}
public static int IndexOf<T>(this T[] a,T e){
for (int n = 0; n < a.Length;n++){
if (Object.Equals(a[n],e)){
return n;
}
}
return -1;
}
}
}

101
HistoryValue.cs 100644
View File

@ -0,0 +1,101 @@
using System;
using System.Security.Policy;
using System.Linq;
namespace sharp.extensions
{
public class HistoryValue<T>
{
T[] values;
int p;
public HistoryValue()
{
this.values = new T[0];
this.p = 0;
}
public HistoryValue(int len)
{
this.values = new T[len];
}
public void Add(T value)
{
this.p = (++this.p) % this.values.Length;
this.values[p] = value;
}
public T this[int i]
{
get
{
if (i < 0)
{
i += this.values.Length;
}
if ((i < 0) || (i >= this.values.Length))
{
throw new IndexOutOfRangeException();
}
i += p;
i %= this.values.Length;
return this.values[i];
}
set
{
if (i < 0)
{
i += this.values.Length;
}
if ((i < 0) || (i >= this.values.Length))
{
throw new IndexOutOfRangeException();
}
i += p;
i %= this.values.Length;
this.values[i] = value;
}
}
public int Count {
get { return this.values.Length; }
}
public T[] History {
get {
T[] pre, post;
if (p == this.values.Length-1){
return this.values.Segment<T>(0);
} else {
pre = this.values.Segment<T>(p + 1);
post = this.values.Segment<T>(0, p + 1);
return pre.Combine<T>(post);
}
}
set {
this.values = value.Segment<T>(0);
this.p = this.values.Length - 1;
}
}
public HistoryValue<T> Clone(){
HistoryValue<T> clone = new HistoryValue<T>();
clone.p = this.p;
clone.values = this.values.Segment<T>(0);
return clone;
}
public static HistoryValue<T> operator +(HistoryValue<T> hvalue,T value){
hvalue.Add(value);
return hvalue;
}
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
namespace sharp.extensions.commandline
{
public class ArgumentReader
{
List<string> arguments = new List<string>();
public string CurrentElement { get; private set; }
public string CurrentOption { get; private set; }
public bool CurrentIsLong { get; private set; }
public bool CurrentIsShort { get; private set; }
public ArgumentReader(String[] arguments)
{
this.arguments.AddRange(arguments);
this.CurrentElement = null;
this.CurrentOption = null;
this.CurrentIsLong = false;
this.CurrentIsShort = false;
}
public bool Next()
{
if (CurrentElement.IsNull() || CurrentElement.Equals(""))
{
if (arguments.Count == 0)
{
return false;
}
CurrentElement = arguments[0];
arguments.RemoveAt(0);
if (CurrentElement.StartsWith("--"))
{
CurrentIsLong = true;
CurrentIsShort = true;
CurrentOption = CurrentElement.Substring(2);
CurrentElement = null;
return true;
}
else if (CurrentElement.StartsWith("-"))
{
CurrentIsLong = false;
CurrentIsShort = true;
CurrentOption = CurrentElement[1].ToString();
CurrentElement = CurrentElement.Substring(2);
return true;
}
CurrentOption = CurrentElement;
CurrentElement = null;
CurrentIsLong = false;
CurrentIsShort = false;
return true;
}
else
{
CurrentOption = CurrentElement[0].ToString();
CurrentElement = CurrentElement.Substring(1);
return true;
}
}
public string PopArgument()
{
string arg = this.arguments[0];
this.arguments.RemoveAt(0);
return arg;
}
}
}

View File

@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace sharp.extensions.commandline
{
public class UnknownArgumentException : Exception {
public UnknownArgumentException(string argument)
:base(string.Format("Argument {0} is not known",argument))
{
}
}
public class Option
{
public char Short { get; private set; }
public string Long { get; private set; }
public bool WasFound { get; set; }
protected Option(char shortoption, string longOption,bool needsArgument)
{
this.Long = longOption;
this.Short = shortoption;
}
public Option(char shortoption, string longOption)
{
this.Long = longOption;
this.Short = shortoption;
}
public Option(char shortOption)
: this(shortOption, null)
{
}
public Option(string longOption)
: this((char)0, longOption)
{
}
public virtual void OptionFound(ArgumentReader reader)
{
WasFound = true;
}
}
public class OptionWithArgument : Option
{
public string Argument { get; private set; }
public OptionWithArgument(char shortoption, string longOption, string defaultArgument = null)
: base(shortoption, longOption, true)
{
Argument = defaultArgument;
}
public OptionWithArgument(string longOption, string defaultArgument = null)
: this((char)0, longOption, defaultArgument)
{
}
public override void OptionFound(ArgumentReader reader)
{
base.OptionFound(reader);
this.Argument = reader.PopArgument();
}
}
public class OptionForEnum<T> : Option where T: struct,IConvertible
{
public T Argument { get; private set; }
public OptionForEnum(char shortoption, string longOption, T defaultArgument = default(T))
: base(shortoption, longOption, true)
{
Argument = defaultArgument;
}
public OptionForEnum(string longOption, T defaultArgument = default(T))
: this((char)0, longOption, defaultArgument)
{
}
public override void OptionFound(ArgumentReader reader)
{
base.OptionFound(reader);
Argument = (T)Enum.Parse(typeof(T), reader.PopArgument());
}
}
public static class OptionExtensions {
public static void ApplyLong(Option[] options, ArgumentReader reader)
{
foreach (Option option in options)
{
if (reader.CurrentOption.Equals(option.Long))
{
option.OptionFound(reader);
return;
}
}
throw new UnknownArgumentException(reader.CurrentOption);
}
public static void ApplyShort(Option[] options, ArgumentReader reader)
{
foreach (Option option in options)
{
if (reader.CurrentOption[0] == option.Short)
{
option.OptionFound(reader);
return;
}
}
throw new UnknownArgumentException(reader.CurrentOption);
}
public static string[] Apply(this Option[] options, string[] args)
{
List<string> rest = new List<string>();
ArgumentReader reader = new ArgumentReader(args);
while (reader.Next()){
if (reader.CurrentIsLong){
ApplyLong(options, reader);
} else if (reader.CurrentIsShort){
ApplyShort(options,reader);
} else {
rest.Add(reader.CurrentOption);
}
}
return rest.ToArray();
}
}
}

View File

@ -29,6 +29,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Runtime.Remoting" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@ -48,8 +49,13 @@
<Compile Include="IConstructorArguments.cs" />
<Compile Include="ConstructableObject.cs" />
<Compile Include="ExtendableThreadPool.cs" />
<Compile Include="ArgumentReader.cs" />
<Compile Include="ObjectExtensions.cs" />
<Compile Include="commandline\ArgumentReader.cs" />
<Compile Include="commandline\Option.cs" />
<Compile Include="HistoryValue.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="commandline\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>