diff --git a/ArgumentReader.cs b/ArgumentReader.cs deleted file mode 100644 index c290c50..0000000 --- a/ArgumentReader.cs +++ /dev/null @@ -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); - } - - } -} diff --git a/Array.cs b/Array.cs index 07c6374..d294a38 100644 --- a/Array.cs +++ b/Array.cs @@ -102,5 +102,14 @@ namespace sharp.extensions return rl.ToArray(); } + public static int IndexOf(this T[] a,T e){ + for (int n = 0; n < a.Length;n++){ + if (Object.Equals(a[n],e)){ + return n; + } + } + return -1; + } + } } diff --git a/HistoryValue.cs b/HistoryValue.cs new file mode 100644 index 0000000..8fa4ecf --- /dev/null +++ b/HistoryValue.cs @@ -0,0 +1,101 @@ +using System; +using System.Security.Policy; +using System.Linq; +namespace sharp.extensions +{ + public class HistoryValue + { + 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(0); + } else { + pre = this.values.Segment(p + 1); + post = this.values.Segment(0, p + 1); + return pre.Combine(post); + } + } + set { + this.values = value.Segment(0); + this.p = this.values.Length - 1; + } + + } + + public HistoryValue Clone(){ + HistoryValue clone = new HistoryValue(); + clone.p = this.p; + clone.values = this.values.Segment(0); + return clone; + } + + + + + public static HistoryValue operator +(HistoryValue hvalue,T value){ + hvalue.Add(value); + return hvalue; + } + + } +} diff --git a/commandline/ArgumentReader.cs b/commandline/ArgumentReader.cs new file mode 100644 index 0000000..2987a09 --- /dev/null +++ b/commandline/ArgumentReader.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Remoting.Messaging; +namespace sharp.extensions.commandline +{ + public class ArgumentReader + { + List arguments = new List(); + + 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; + } + + } +} diff --git a/commandline/Option.cs b/commandline/Option.cs new file mode 100644 index 0000000..6063fcb --- /dev/null +++ b/commandline/Option.cs @@ -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 : 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 rest = new List(); + 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(); + } + + } + +} diff --git a/sharp.extensions.csproj b/sharp.extensions.csproj index da07a2d..296a4d7 100644 --- a/sharp.extensions.csproj +++ b/sharp.extensions.csproj @@ -29,6 +29,7 @@ + @@ -48,8 +49,13 @@ - + + + + + +