1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585 |
- #region
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- #endregion
- namespace CassiniDev
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public sealed class CommandLineParser
- {
-
-
-
- public const string NewLine = "\r\n";
- private const int SpaceBeforeParam = 2;
- private const int StdOutputHandle = -11;
- private readonly Hashtable _argumentMap;
- private readonly ArrayList _arguments;
- private readonly Type _argumentSpecification;
- private readonly Argument _defaultArgument;
- private readonly ErrorReporter _reporter;
-
-
-
-
- private CommandLineParser()
-
- {
-
- }
-
-
-
-
-
- public CommandLineParser(Type argumentSpecification, ErrorReporter reporter)
- {
- _argumentSpecification = argumentSpecification;
- _reporter = reporter;
- _arguments = new ArrayList();
- _argumentMap = new Hashtable();
- foreach (FieldInfo field in argumentSpecification.GetFields())
- {
- if (!field.IsStatic && !field.IsInitOnly && !field.IsLiteral)
- {
- ArgumentAttribute attribute = GetAttribute(field);
- if (attribute is DefaultArgumentAttribute)
- {
- Debug.Assert(_defaultArgument == null);
- _defaultArgument = new Argument(attribute, field, reporter);
- }
- else
- {
- _arguments.Add(new Argument(attribute, field, reporter));
- }
- }
- }
-
- foreach (Argument argument in _arguments)
- {
- Debug.Assert(!_argumentMap.ContainsKey(argument.LongName));
- _argumentMap[argument.LongName] = argument;
- if (argument.ExplicitShortName)
- {
- if (!string.IsNullOrEmpty(argument.ShortName))
- {
- Debug.Assert(!_argumentMap.ContainsKey(argument.ShortName));
- _argumentMap[argument.ShortName] = argument;
- }
- else
- {
- argument.ClearShortName();
- }
- }
- }
-
- foreach (Argument argument in _arguments)
- {
- if (!argument.ExplicitShortName)
- {
- if (!string.IsNullOrEmpty(argument.ShortName) && !_argumentMap.ContainsKey(argument.ShortName))
- _argumentMap[argument.ShortName] = argument;
- else
- argument.ClearShortName();
- }
- }
- }
-
-
-
-
- public bool HasDefaultArgument
- {
- get { return _defaultArgument != null; }
- }
-
-
-
-
-
-
-
- public static string ArgumentsUsage(Type argumentType)
- {
- int screenWidth = GetConsoleWindowWidth();
- if (screenWidth == 0)
- screenWidth = 80;
- return ArgumentsUsage(argumentType, screenWidth);
- }
-
-
-
-
-
-
-
- public static string ArgumentsUsage(Type argumentType, int columns)
- {
- return (new CommandLineParser(argumentType, null)).GetUsageString(columns);
- }
-
-
-
-
- public static int GetConsoleWindowWidth()
- {
- Interop.CONSOLE_SCREEN_BUFFER_INFO csbi = new Interop.CONSOLE_SCREEN_BUFFER_INFO();
- #pragma warning disable 168
- int rc = Interop.GetConsoleScreenBufferInfo(Interop.GetStdHandle(StdOutputHandle), ref csbi);
- #pragma warning restore 168
- int screenWidth = csbi.dwSize.x;
- return screenWidth;
- }
-
-
-
- public string GetUsageString(int screenWidth)
- {
- ArgumentHelpStrings[] strings = GetAllHelpStrings();
- int maxParamLen = 0;
- foreach (ArgumentHelpStrings helpString in strings)
- {
- maxParamLen = Math.Max(maxParamLen, helpString.syntax.Length);
- }
- const int minimumNumberOfCharsForHelpText = 10;
- const int minimumHelpTextColumn = 5;
- const int minimumScreenWidth = minimumHelpTextColumn + minimumNumberOfCharsForHelpText;
- int idealMinimumHelpTextColumn = maxParamLen + SpaceBeforeParam;
- screenWidth = Math.Max(screenWidth, minimumScreenWidth);
- int helpTextColumn = screenWidth < (idealMinimumHelpTextColumn + minimumNumberOfCharsForHelpText)
- ? minimumHelpTextColumn
- : idealMinimumHelpTextColumn;
- const string newLine = "\n";
- StringBuilder builder = new StringBuilder();
-
- string genericUsage = GetGenericUsageString(_argumentSpecification, screenWidth);
- if (!string.IsNullOrEmpty(genericUsage))
- {
- builder.AppendLine(genericUsage);
- }
- foreach (ArgumentHelpStrings helpStrings in strings)
- {
-
- int syntaxLength = helpStrings.syntax.Length;
- builder.Append(helpStrings.syntax);
-
- int currentColumn = syntaxLength;
- if (syntaxLength >= helpTextColumn)
- {
- builder.Append(newLine);
- currentColumn = 0;
- }
-
- int charsPerLine = screenWidth - helpTextColumn;
- int index = 0;
- while (index < helpStrings.help.Length)
- {
-
- builder.Append(' ', helpTextColumn - currentColumn);
- currentColumn = helpTextColumn;
-
- int endIndex = index + charsPerLine;
- if (endIndex >= helpStrings.help.Length)
- {
-
- endIndex = helpStrings.help.Length;
- }
- else
- {
- endIndex = helpStrings.help.LastIndexOf(' ', endIndex - 1,
- Math.Min(endIndex - index, charsPerLine));
- if (endIndex <= index)
- {
-
- endIndex = index + charsPerLine;
- }
- }
-
- builder.Append(helpStrings.help, index, endIndex - index);
- index = endIndex;
-
- AddNewLine(newLine, builder, ref currentColumn);
-
- while (index < helpStrings.help.Length && helpStrings.help[index] == ' ')
- index++;
- }
-
- if (helpStrings.help.Length == 0)
- {
- builder.Append(newLine);
- }
- }
- return builder.ToString();
- }
-
-
-
-
-
-
-
- public static int IndexOf(StringBuilder text, char value, int startIndex)
- {
- for (int index = startIndex; index < text.Length; index++)
- {
- if (text[index] == value)
- return index;
- }
- return -1;
- }
-
-
-
-
-
-
-
- public static int LastIndexOf(StringBuilder text, char value, int startIndex)
- {
- for (int index = Math.Min(startIndex, text.Length - 1); index >= 0; index--)
- {
- if (text[index] == value)
- return index;
- }
- return -1;
- }
-
-
-
-
-
-
- public bool Parse(string[] args, object destination)
- {
- bool hadError = ParseArgumentList(args, destination);
-
- foreach (Argument arg in _arguments)
- {
- hadError |= arg.Finish(destination);
- }
- if (_defaultArgument != null)
- {
- hadError |= _defaultArgument.Finish(destination);
- }
- return !hadError;
- }
-
-
-
-
-
-
-
-
- public static bool ParseArguments(string[] arguments, object destination)
- {
- return ParseArguments(arguments, destination, Console.Error.WriteLine);
- }
-
-
-
-
-
-
-
-
- public static bool ParseArguments(string[] arguments, object destination, ErrorReporter reporter)
- {
- CommandLineParser parser = new CommandLineParser(destination.GetType(), reporter);
- return parser.Parse(arguments, destination);
- }
-
-
-
-
-
-
-
-
-
- public static bool ParseArgumentsWithUsage(string[] arguments, object destination)
- {
- if (ParseHelp(arguments) || !ParseArguments(arguments, destination))
- {
-
- Console.Write(ArgumentsUsage(destination.GetType()));
- return false;
- }
- return true;
- }
-
-
-
-
-
- public static bool ParseHelp(string[] args)
- {
- CommandLineParser helpParser = new CommandLineParser(typeof (HelpArgument), NullErrorReporter);
- HelpArgument helpArgument = new HelpArgument();
- helpParser.Parse(args, helpArgument);
- return helpArgument.help;
- }
- private static void AddNewLine(string newLine, StringBuilder builder, ref int currentColumn)
- {
- builder.Append(newLine);
- currentColumn = 0;
- }
- private static object DefaultValue(ArgumentAttribute attribute)
- {
- return (attribute == null || !attribute.HasDefaultValue) ? null : attribute.DefaultValue;
- }
- private static Type ElementType(FieldInfo field)
- {
- return IsCollectionType(field.FieldType) ? field.FieldType.GetElementType() : null;
- }
- private static bool ExplicitShortName(ArgumentAttribute attribute)
- {
- return (attribute != null && !attribute.DefaultShortName);
- }
- private static ArgumentType Flags(ArgumentAttribute attribute, FieldInfo field)
- {
- if (attribute != null)
- {
- return attribute.Type;
- }
- return IsCollectionType(field.FieldType) ? ArgumentType.MultipleUnique : ArgumentType.AtMostOnce;
- }
- private ArgumentHelpStrings[] GetAllHelpStrings()
- {
- ArgumentHelpStrings[] strings = new ArgumentHelpStrings[NumberOfParametersToDisplay()];
- int index = 0;
- foreach (Argument arg in _arguments)
- {
- strings[index] = GetHelpStrings(arg);
- index++;
- }
- strings[index++] = new ArgumentHelpStrings("@<file>", "Read response file for more options");
- if (_defaultArgument != null)
- {
- strings[index] = GetHelpStrings(_defaultArgument);
- }
- return strings;
- }
- private static ArgumentAttribute GetAttribute(ICustomAttributeProvider field)
- {
- object[] attributes = field.GetCustomAttributes(typeof (ArgumentAttribute), false);
- if (attributes.Length == 1)
- return (ArgumentAttribute) attributes[0];
- Debug.Assert(attributes.Length == 0);
- return null;
- }
-
-
-
- private static string GetGenericUsageString(ICustomAttributeProvider type, int cols)
- {
- object[] attributes = type.GetCustomAttributes(typeof (ArgumentsAttribute), true);
- if (attributes.Length == 0 || !((ArgumentsAttribute) attributes[0]).HasHelpText)
- {
- return string.Empty;
- }
- StringBuilder sb = new StringBuilder();
- string usage = ((ArgumentsAttribute) attributes[0]).HelpText;
-
- string[] lines = Regex.Split(usage, Environment.NewLine);
- foreach (string line in lines)
- {
- string[] words = Regex.Split(line, " ");
- string currentLine = string.Empty;
- foreach (string word in words)
- {
- if (currentLine.Length + word.Length + 1 > cols)
- {
-
- sb.AppendLine(currentLine);
- currentLine = word + " ";
- }
- else
- {
- currentLine += (word + " ");
- }
- }
- sb.AppendLine(currentLine);
- sb.Append(Environment.NewLine);
- }
- return sb.ToString();
- }
- private static ArgumentHelpStrings GetHelpStrings(Argument arg)
- {
- return new ArgumentHelpStrings(arg.SyntaxHelp, arg.FullHelpText);
- }
- private static bool HasHelpText(ArgumentAttribute attribute)
- {
- return (attribute != null && attribute.HasHelpText);
- }
- private static string HelpText(ArgumentAttribute attribute)
- {
- return attribute == null ? null : attribute.HelpText;
- }
- private static bool IsCollectionType(Type type)
- {
- return type.IsArray;
- }
- private static bool IsValidElementType(Type type)
- {
-
- return type != null && (
- type == typeof (int) ||
- type == typeof (uint) ||
- type == typeof (ushort) ||
- type == typeof (string) ||
- type == typeof (bool) ||
- type.IsEnum);
- }
- private bool LexFileArguments(string fileName, out string[] argumentsOut)
- {
- string args;
- try
- {
- using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- args = (new StreamReader(file)).ReadToEnd();
- }
- }
- catch (Exception e)
- {
- _reporter(string.Format("Error: Can't open command line argument file '{0}' : '{1}'", fileName,
- e.Message));
- argumentsOut = null;
- return false;
- }
- bool hadError = false;
- ArrayList argArray = new ArrayList();
- StringBuilder currentArg = new StringBuilder();
- bool inQuotes = false;
- int index = 0;
-
- try
- {
- while (true)
- {
-
- while (char.IsWhiteSpace(args[index]))
- {
- index += 1;
- }
-
- if (args[index] == '#')
- {
- index += 1;
- while (args[index] != '\n')
- {
- index += 1;
- }
- continue;
- }
-
- do
- {
- if (args[index] == '\\')
- {
- int cSlashes = 1;
- index += 1;
- while (index == args.Length && args[index] == '\\')
- {
- cSlashes += 1;
- }
- if (index == args.Length || args[index] != '"')
- {
- currentArg.Append('\\', cSlashes);
- }
- else
- {
- currentArg.Append('\\', (cSlashes >> 1));
- if (0 != (cSlashes & 1))
- {
- currentArg.Append('"');
- }
- else
- {
- inQuotes = !inQuotes;
- }
- }
- }
- else if (args[index] == '"')
- {
- inQuotes = !inQuotes;
- index += 1;
- }
- else
- {
- currentArg.Append(args[index]);
- index += 1;
- }
- } while (!char.IsWhiteSpace(args[index]) || inQuotes);
- argArray.Add(currentArg.ToString());
- currentArg.Length = 0;
- }
- }
- catch (IndexOutOfRangeException)
- {
-
- if (inQuotes)
- {
- _reporter(string.Format("Error: Unbalanced '\"' in command line argument file '{0}'", fileName));
- hadError = true;
- }
- else if (currentArg.Length > 0)
- {
-
- argArray.Add(currentArg.ToString());
- }
- }
- argumentsOut = (string[]) argArray.ToArray(typeof (string));
- return hadError;
- }
- private static string LongName(ArgumentAttribute attribute, FieldInfo field)
- {
- return (attribute == null || attribute.DefaultLongName) ? field.Name : attribute.LongName;
- }
- private static void NullErrorReporter(string message)
- {
- }
- private int NumberOfParametersToDisplay()
- {
- int numberOfParameters = _arguments.Count + 1;
- if (HasDefaultArgument)
- {
- numberOfParameters += 1;
- }
- return numberOfParameters;
- }
-
-
-
-
-
-
- private bool ParseArgumentList(IEnumerable<string> args, object destination)
- {
- bool hadError = false;
- if (args != null)
- {
- foreach (string argument in args)
- {
- if (argument.Length > 0)
- {
- switch (argument[0])
- {
- case '-':
- case '/':
- int endIndex = argument.IndexOfAny(new[] {':', '+', '-'}, 1);
- string option = argument.Substring(1,
- endIndex == -1 ? argument.Length - 1 : endIndex - 1);
- string optionArgument;
- if (option.Length + 1 == argument.Length)
- {
- optionArgument = null;
- }
- else if (argument.Length > 1 + option.Length && argument[1 + option.Length] == ':')
- {
- optionArgument = argument.Substring(option.Length + 2);
- }
- else
- {
- optionArgument = argument.Substring(option.Length + 1);
- }
- Argument arg = (Argument) _argumentMap[option];
- if (arg == null)
- {
- ReportUnrecognizedArgument(argument);
- hadError = true;
- }
- else
- {
- hadError |= !arg.SetValue(optionArgument, destination);
- }
- break;
- case '@':
- string[] nestedArguments;
- hadError |= LexFileArguments(argument.Substring(1), out nestedArguments);
- hadError |= ParseArgumentList(nestedArguments, destination);
- break;
- default:
- if (_defaultArgument != null)
- {
- hadError |= !_defaultArgument.SetValue(argument, destination);
- }
- else
- {
- ReportUnrecognizedArgument(argument);
- hadError = true;
- }
- break;
- }
- }
- }
- }
- return hadError;
- }
- private void ReportUnrecognizedArgument(string argument)
- {
- _reporter(string.Format("Unrecognized command line argument '{0}'", argument));
- }
- private static string ShortName(ArgumentAttribute attribute, FieldInfo field)
- {
- if (attribute is DefaultArgumentAttribute)
- return null;
- if (!ExplicitShortName(attribute))
- return LongName(attribute, field).Substring(0, 1);
- return attribute.ShortName;
- }
- #region Nested type: Argument
- [DebuggerDisplay("Name = {LongName}")]
- private class Argument
- {
- private readonly ArrayList _collectionValues;
- private readonly object _defaultValue;
- private readonly Type _elementType;
- private readonly bool _explicitShortName;
- private readonly FieldInfo _field;
- private readonly ArgumentType _flags;
- private readonly bool _hasHelpText;
- private readonly string _helpText;
- private readonly bool _isDefault;
- private readonly string _longName;
- private readonly ErrorReporter _reporter;
- private bool _seenValue;
- private string _shortName;
- public Argument(ArgumentAttribute attribute, FieldInfo field, ErrorReporter reporter)
- {
- _longName = CommandLineParser.LongName(attribute, field);
- _explicitShortName = CommandLineParser.ExplicitShortName(attribute);
- _shortName = CommandLineParser.ShortName(attribute, field);
- _hasHelpText = CommandLineParser.HasHelpText(attribute);
- _helpText = CommandLineParser.HelpText(attribute);
- _defaultValue = CommandLineParser.DefaultValue(attribute);
- _elementType = ElementType(field);
- _flags = Flags(attribute, field);
- _field = field;
- _seenValue = false;
- _reporter = reporter;
- _isDefault = attribute != null && attribute is DefaultArgumentAttribute;
- if (IsCollection)
- {
- _collectionValues = new ArrayList();
- }
- Debug.Assert(!string.IsNullOrEmpty(_longName));
- Debug.Assert(!_isDefault || !ExplicitShortName);
- Debug.Assert(!IsCollection || AllowMultiple, "Collection arguments must have allow multiple");
- Debug.Assert(!Unique || IsCollection, "Unique only applicable to collection arguments");
- Debug.Assert(IsValidElementType(Type) || IsCollectionType(Type));
- Debug.Assert((IsCollection && IsValidElementType(_elementType)) ||
- (!IsCollection && _elementType == null));
- Debug.Assert(!(IsRequired && HasDefaultValue), "Required arguments cannot have default value");
- Debug.Assert(!HasDefaultValue || (_defaultValue.GetType() == field.FieldType),
- "Type of default value must match field type");
- }
- private Type ValueType
- {
- get { return IsCollection ? _elementType : Type; }
- }
- public string LongName
- {
- get { return _longName; }
- }
- public bool ExplicitShortName
- {
- get { return _explicitShortName; }
- }
- public string ShortName
- {
- get { return _shortName; }
- }
- private bool HasShortName
- {
- get { return _shortName != null; }
- }
- private bool HasHelpText
- {
- get { return _hasHelpText; }
- }
- private string HelpText
- {
- get { return _helpText; }
- }
- private object DefaultValue
- {
- get { return _defaultValue; }
- }
- private bool HasDefaultValue
- {
- get { return null != _defaultValue; }
- }
- public string FullHelpText
- {
- get
- {
- StringBuilder builder = new StringBuilder();
- if (HasHelpText)
- {
- builder.Append(HelpText);
- }
- if (HasDefaultValue)
- {
- if (builder.Length > 0)
- builder.Append(" ");
- builder.Append("Default value:'");
- AppendValue(builder, DefaultValue);
- builder.Append('\'');
- }
- if (HasShortName)
- {
- if (builder.Length > 0)
- builder.Append(" ");
- builder.Append("(short form /");
- builder.Append(ShortName);
- builder.Append(")");
- }
- return builder.ToString();
- }
- }
- public string SyntaxHelp
- {
- get
- {
- StringBuilder builder = new StringBuilder();
- if (IsDefault)
- {
- builder.Append("<");
- builder.Append(LongName);
- builder.Append(">");
- }
- else
- {
- builder.Append("/");
- builder.Append(LongName);
- Type valueType = ValueType;
- if (valueType == typeof (int))
- {
- builder.Append(":<int>");
- }
- else if (valueType == typeof (uint))
- {
- builder.Append(":<uint>");
- }
- else if (valueType == typeof (bool))
- {
- builder.Append("[+|-]");
- }
- else if (valueType == typeof (string))
- {
- builder.Append(":<string>");
- }
- else
- {
- Debug.Assert(valueType.IsEnum);
- builder.Append(":{");
- bool first = true;
- foreach (FieldInfo info in valueType.GetFields())
- {
- if (info.IsStatic)
- {
- if (first)
- first = false;
- else
- builder.Append('|');
- builder.Append(info.Name);
- }
- }
- builder.Append('}');
- }
- }
- return builder.ToString();
- }
- }
- private bool IsRequired
- {
- get { return 0 != (_flags & ArgumentType.Required); }
- }
- private bool SeenValue
- {
- get { return _seenValue; }
- }
- private bool AllowMultiple
- {
- get { return 0 != (_flags & ArgumentType.Multiple); }
- }
- private bool Unique
- {
- get { return 0 != (_flags & ArgumentType.Unique); }
- }
- private Type Type
- {
- get { return _field.FieldType; }
- }
- private bool IsCollection
- {
- get { return IsCollectionType(Type); }
- }
- private bool IsDefault
- {
- get { return _isDefault; }
- }
- public bool Finish(object destination)
- {
- if (SeenValue)
- {
- if (IsCollection)
- {
- _field.SetValue(destination, _collectionValues.ToArray(_elementType));
- }
- }
- else
- {
- if (HasDefaultValue)
- {
- _field.SetValue(destination, DefaultValue);
- }
- }
- return ReportMissingRequiredArgument();
- }
- private bool ReportMissingRequiredArgument()
- {
- if (IsRequired && !SeenValue)
- {
- if (IsDefault)
- _reporter(string.Format("Missing required argument '<{0}>'.", LongName));
- else
- _reporter(string.Format("Missing required argument '/{0}'.", LongName));
- return true;
- }
- return false;
- }
- private void ReportDuplicateArgumentValue(string value)
- {
- _reporter(string.Format("Duplicate '{0}' argument '{1}'", LongName, value));
- }
- public bool SetValue(string value, object destination)
- {
- if (SeenValue && !AllowMultiple)
- {
- _reporter(string.Format("Duplicate '{0}' argument", LongName));
- return false;
- }
- _seenValue = true;
- object newValue;
- if (!ParseValue(ValueType, value, out newValue))
- {
- return false;
- }
- if (IsCollection)
- {
- if (Unique && _collectionValues.Contains(newValue))
- {
- ReportDuplicateArgumentValue(value);
- return false;
- }
- _collectionValues.Add(newValue);
- }
- else
- {
- _field.SetValue(destination, newValue);
- }
- return true;
- }
- private void ReportBadArgumentValue(string value)
- {
- _reporter(string.Format("'{0}' is not a valid value for the '{1}' command line option", value, LongName));
- }
- private bool ParseValue(Type type, string stringData, out object value)
- {
-
-
- if (!string.IsNullOrEmpty(stringData) || type == typeof (bool))
- {
- try
- {
- do
- {
- if (type == typeof (string))
- {
- value = stringData;
- return true;
- }
- if (type == typeof (bool))
- {
- if (stringData == null || stringData == "+")
- {
- value = true;
- return true;
- }
- if (stringData == "-")
- {
- value = false;
- return true;
- }
- break;
- }
-
- if (string.IsNullOrEmpty(stringData))
- {
- break;
- }
- if (type == typeof (int))
- {
- value = int.Parse(stringData);
- return true;
- }
- if (type == typeof (uint))
- {
- value = int.Parse(stringData);
- return true;
- }
-
- if (type == typeof (ushort))
- {
- value = ushort.Parse(stringData);
- return true;
- }
- Debug.Assert(type.IsEnum);
- bool valid = false;
- foreach (string name in Enum.GetNames(type))
- {
- if (string.Compare(name, stringData, StringComparison.InvariantCultureIgnoreCase) == 0)
- {
- valid = true;
- break;
- }
- }
- if (valid)
- {
- value = Enum.Parse(type, stringData, true);
- return true;
- }
- } while (false);
- }
-
- catch
-
- {
-
- }
- }
- ReportBadArgumentValue(stringData);
- value = null;
- return false;
- }
- private static void AppendValue(StringBuilder builder, object value)
- {
-
- if (value is string || value is int || value is uint || value is ushort || value.GetType().IsEnum)
- {
- builder.Append(value.ToString());
- }
- else if (value is bool)
- {
- builder.Append((bool) value ? "+" : "-");
- }
- else
- {
- bool first = true;
- foreach (object o in (Array) value)
- {
- if (!first)
- {
- builder.Append(", ");
- }
- AppendValue(builder, o);
- first = false;
- }
- }
- }
- public void ClearShortName()
- {
- _shortName = null;
- }
- }
- #endregion
- #region Nested type: ArgumentHelpStrings
- private struct ArgumentHelpStrings
- {
- public readonly string help;
- public readonly string syntax;
- public ArgumentHelpStrings(string syntax, string help)
- {
- this.syntax = syntax;
- this.help = help;
- }
- }
- #endregion
- #region Nested type: HelpArgument
- private class HelpArgument
- {
- [Argument(ArgumentType.AtMostOnce, ShortName = "?")] public bool help;
- }
- #endregion
- }
-
-
-
- public delegate void ErrorReporter(string message);
-
-
-
-
-
-
-
- [AttributeUsage(AttributeTargets.Field)]
- public class DefaultArgumentAttribute : ArgumentAttribute
- {
-
-
-
-
- public DefaultArgumentAttribute(ArgumentType type)
- : base(type)
- {
- }
- }
-
-
-
- [Flags]
- public enum ArgumentType
- {
-
-
-
-
- Required = 0x01,
-
-
-
-
- Unique = 0x02,
-
-
-
-
- Multiple = 0x04,
-
-
-
-
- AtMostOnce = 0x00,
-
-
-
-
-
- LastOccurenceWins = Multiple,
-
-
-
-
-
- MultipleUnique = Multiple | Unique,
- }
-
-
-
-
-
- [AttributeUsage(AttributeTargets.Class)]
- public class ArgumentsAttribute : Attribute
- {
- private string _helpText;
-
-
-
- public bool HasHelpText
- {
- get { return null != _helpText; }
- }
-
-
-
- public string HelpText
- {
- get { return _helpText; }
- set { _helpText = value; }
- }
- }
-
-
-
-
-
- [AttributeUsage(AttributeTargets.Field)]
- public class ArgumentAttribute : Attribute
- {
- #region Fields
- private readonly ArgumentType _type;
- private object _defaultValue;
- private string _helpText;
- private string _longName;
- private string _shortName;
- #endregion
- #region Constructors
-
-
-
-
- public ArgumentAttribute(ArgumentType type)
- {
- _type = type;
- }
- #endregion
- #region Properties
-
-
-
- public bool DefaultLongName
- {
- get { return null == _longName; }
- }
-
-
-
- public bool DefaultShortName
- {
- get { return null == _shortName; }
- }
-
-
-
- public object DefaultValue
- {
- get { return _defaultValue; }
- set { _defaultValue = value; }
- }
-
-
-
- public bool HasDefaultValue
- {
- get { return null != _defaultValue; }
- }
-
-
-
- public bool HasHelpText
- {
- get { return null != _helpText; }
- }
-
-
-
- public string HelpText
- {
- get { return _helpText; }
- set { _helpText = value; }
- }
-
-
-
-
-
-
- public string LongName
- {
- get
- {
- Debug.Assert(!DefaultLongName);
- return _longName;
- }
- set
- {
- Debug.Assert(value != "");
- _longName = value;
- }
- }
-
-
-
-
-
-
-
- public string ShortName
- {
- get { return _shortName; }
- set
- {
- Debug.Assert(value == null || !(this is DefaultArgumentAttribute));
- _shortName = value;
- }
- }
-
-
-
- public ArgumentType Type
- {
- get { return _type; }
- }
- #endregion
- }
- }
|