Showing preview only (4,980K chars total). The displayed content is truncated. Use the JSON API for full output.
Repository: adrianaisemberg/CLAP
Branch: master
Commit: 225b7be1cc70
Files: 129
Total size: 4.7 MB
Directory structure:
gitextract_kfd419ot/
├── .gitignore
├── CLAP/
│ ├── CLAP.csproj
│ ├── CollectionValidationAttribute.cs
│ ├── CoverageExcludeAttribute.cs
│ ├── DefaultHelpGenerator.cs
│ ├── DefaultProvider.cs
│ ├── EmptyAttribute.cs
│ ├── EnvironmentParserHandlers.cs
│ ├── ErrorAttribute.cs
│ ├── ExceptionContext.cs
│ ├── Exceptions.cs
│ ├── FW2Stuff.cs
│ ├── FileSystemHelper.cs
│ ├── GlobalAttribute.cs
│ ├── HelpAttribute.cs
│ ├── HelpGeneratorBase.cs
│ ├── HelpInfo.cs
│ ├── IValidation.cs
│ ├── Interception/
│ │ ├── IVerbInterceptor.cs
│ │ ├── ParameterAndValue.cs
│ │ ├── PostVerbExecutionAttribute.cs
│ │ ├── PostVerbExecutionContext.cs
│ │ ├── PreVerbExecutionAttribute.cs
│ │ ├── PreVerbExecutionContext.cs
│ │ ├── UserVerbExecutionContext.cs
│ │ └── VerbInterception.cs
│ ├── Method.cs
│ ├── MethodInvoker.cs
│ ├── MultiParser.cs
│ ├── Pair.cs
│ ├── Parameter.cs
│ ├── ParameterAttribute.cs
│ ├── ParametersExpressionValidator.cs
│ ├── Parser.Console.cs
│ ├── Parser.WinForms.cs
│ ├── Parser.cs
│ ├── ParserRegistration.cs
│ ├── ParserRunner.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Publish/
│ │ ├── CLAP.nuspec
│ │ └── pack.cmd
│ ├── Serialization.cs
│ ├── TargetResolver.cs
│ ├── TypeValidator.cs
│ ├── Utils.cs
│ ├── Validation/
│ │ ├── DirectoryExistsAttribute.cs
│ │ ├── FileExistsAttribute.cs
│ │ ├── Less.cs
│ │ ├── LessOrEqual.cs
│ │ ├── More.cs
│ │ ├── MoreOrEqual.cs
│ │ ├── NumberValidator.cs
│ │ ├── PathExistsAttribute.cs
│ │ ├── Regex.cs
│ │ └── ValidateAttribute.cs
│ ├── ValidationAttribute.cs
│ ├── ValueInfo.cs
│ ├── ValuesFactory.cs
│ ├── VerbAttribute.cs
│ ├── VerbExecutionContext.cs
│ └── packages.config
├── CLAP.sln
├── ConsoleTest/
│ ├── ConsoleTest.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── app.config
├── README.md
├── Tests/
│ ├── MultiParserTests.cs
│ ├── ParserRegistrationTests.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Samples.cs
│ ├── StaticSamples.cs
│ ├── Tests.cs
│ ├── Tests.csproj
│ ├── UtilsTests.cs
│ └── packages.config
├── WinFormTest/
│ ├── Form1.Designer.cs
│ ├── Form1.cs
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ └── Settings.settings
│ └── WinFormTest.csproj
├── license.txt
└── packages/
├── Moq.4.0.10827/
│ ├── License.txt
│ ├── Moq.chm
│ └── lib/
│ ├── NET35/
│ │ ├── Moq.pdb
│ │ └── Moq.xml
│ ├── NET40/
│ │ ├── Moq.pdb
│ │ └── Moq.xml
│ └── Silverlight4/
│ ├── Moq.Silverlight.pdb
│ └── Moq.Silverlight.xml
├── NUnit.2.5.10.11092/
│ ├── NUnitFitTests.html
│ ├── fit-license.txt
│ ├── lib/
│ │ └── nunit.framework.xml
│ ├── license.txt
│ └── tools/
│ ├── NUnitTests.VisualState.xml
│ ├── NUnitTests.config
│ ├── NUnitTests.nunit
│ ├── TestResult.xml
│ ├── agent.conf
│ ├── agent.log.conf
│ ├── launcher.log.conf
│ ├── nunit-agent-x86.exe.config
│ ├── nunit-agent.exe.config
│ ├── nunit-console-x86.exe.config
│ ├── nunit-console.exe.config
│ ├── nunit-x86.exe.config
│ ├── nunit.exe.config
│ ├── pnunit-agent.exe.config
│ ├── pnunit-launcher.exe.config
│ ├── runFile.exe.config
│ ├── runpnunit.bat
│ └── test.conf
├── Newtonsoft.Json.4.0.8/
│ └── lib/
│ ├── net20/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── net35/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── net40/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── sl3-wp/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── sl4/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ └── sl4-windowsphone71/
│ ├── Newtonsoft.Json.pdb
│ └── Newtonsoft.Json.xml
└── repositories.config
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.docstates
*.suo
*.user
bin
obj
UpgradeLog.XML
_UpgradeReport_Files/
*.nupkg
/_ReSharper.*/
/Metrics.typemock.*
================================================
FILE: CLAP/CLAP.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{AE79CD7B-DFFC-4156-913E-63F70A31B7C1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CLAP</RootNamespace>
<AssemblyName>CLAP</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin\Debug\CLAP.XML</DocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>bin\Release\CLAP.XML</DocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release20|AnyCPU'">
<OutputPath>bin\Release20\</OutputPath>
<DefineConstants>TRACE;FW2</DefineConstants>
<DocumentationFile>bin\Release20\CLAP.XML</DocumentationFile>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<Optimize>true</Optimize>
<NoWarn>1591</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Release20\CLAP.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Condition="'$(Configuration)' != 'Release20'" Include="Newtonsoft.Json, Version=4.0.8.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.4.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Condition="'$(Configuration)' == 'Release20'" Include="Newtonsoft.Json, Version=4.0.8.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.4.0.8\lib\net20\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CollectionValidationAttribute.cs" />
<Compile Include="DefaultProvider.cs" />
<Compile Include="HelpGeneratorBase.cs" />
<Compile Include="HelpInfo.cs" />
<Compile Include="Interception\UserVerbExecutionContext.cs" />
<Compile Include="Pair.cs" />
<Compile Include="Parser.WinForms.cs" />
<Compile Include="EnvironmentParserHandlers.cs" />
<Compile Include="Parser.Console.cs" />
<Compile Include="CoverageExcludeAttribute.cs" />
<Compile Include="ErrorAttribute.cs" />
<Compile Include="ExceptionContext.cs" />
<Compile Include="FileSystemHelper.cs" />
<Compile Include="FW2Stuff.cs" />
<Compile Include="EmptyAttribute.cs" />
<Compile Include="Exceptions.cs" />
<Compile Include="GlobalAttribute.cs" />
<Compile Include="DefaultHelpGenerator.cs" />
<Compile Include="Interception\IVerbInterceptor.cs" />
<Compile Include="Interception\PostVerbExecutionAttribute.cs" />
<Compile Include="Interception\PostVerbExecutionContext.cs" />
<Compile Include="Interception\ParameterAndValue.cs" />
<Compile Include="Interception\PreVerbExecutionAttribute.cs" />
<Compile Include="Interception\PreVerbExecutionContext.cs" />
<Compile Include="TargetResolver.cs" />
<Compile Include="VerbExecutionContext.cs" />
<Compile Include="Interception\VerbInterception.cs" />
<Compile Include="Method.cs" />
<Compile Include="MethodInvoker.cs" />
<Compile Include="MultiParser.cs" />
<Compile Include="Parameter.cs" />
<Compile Include="ParameterAttribute.cs" />
<Compile Include="ParametersExpressionValidator.cs" />
<Compile Include="Parser.cs" />
<Compile Include="IValidation.cs" />
<Compile Include="ParserRunner.cs" />
<Compile Include="ParserRegistration.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Serialization.cs" />
<Compile Include="TypeValidator.cs" />
<Compile Include="Utils.cs" />
<Compile Include="ValidationAttribute.cs" />
<Compile Include="HelpAttribute.cs" />
<Compile Include="Validation\PathExistsAttribute.cs" />
<Compile Include="Validation\DirectoryExistsAttribute.cs" />
<Compile Include="Validation\FileExistsAttribute.cs" />
<Compile Include="Validation\Less.cs" />
<Compile Include="Validation\LessOrEqual.cs" />
<Compile Include="Validation\More.cs" />
<Compile Include="Validation\MoreOrEqual.cs" />
<Compile Include="Validation\NumberValidator.cs" />
<Compile Include="Validation\Regex.cs" />
<Compile Include="Validation\ValidateAttribute.cs" />
<Compile Include="ValueInfo.cs" />
<Compile Include="ValuesFactory.cs" />
<Compile Include="VerbAttribute.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
================================================
FILE: CLAP/CollectionValidationAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// Validates a collection of parameters of properties
/// </summary>
public abstract class CollectionValidationAttribute : Attribute, ICollectionValidation
{
/// <summary>
/// Gets a validator instance
/// </summary>
public abstract ICollectionValidator GetValidator();
/// <summary>
/// The validation description
/// </summary>
public abstract string Description { get; }
}
}
================================================
FILE: CLAP/CoverageExcludeAttribute.cs
================================================
internal class CoverageExcludeAttribute : System.Attribute { }
================================================
FILE: CLAP/DefaultHelpGenerator.cs
================================================
using System;
using System.Text;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
internal class DefaultHelpGenerator : HelpGeneratorBase
{
protected override string GetHelpString(HelpInfo helpInfo)
{
const string verbsLead = " ";
const string parametersLead = " ";
const string validationsLead = " ";
var sb = new StringBuilder();
var count = helpInfo.Parsers.Count;
var multi = count > 1;
for (int i = 0; i < count; i++)
{
var parser = helpInfo.Parsers[i];
foreach (var verb in parser.Verbs.OrderByDescending(v => v.IsDefault))
{
sb.AppendLine();
sb.Append(verbsLead);
if (multi)
{
sb.AppendFormat("{0}.", parser.Type.Name.ToLowerInvariant());
}
sb.Append(verb.Names.StringJoin("|").ToLowerInvariant());
if (verb.IsDefault)
{
sb.Append(" (Default)");
}
if (!string.IsNullOrEmpty(verb.Description))
{
sb.AppendFormat(": {0}", verb.Description);
}
sb.AppendLine();
if (verb.Parameters.Any())
{
var longestParameter = verb.Parameters.Max(p => p.Names.StringJoin(" /").Length);
var longestType = verb.Parameters.Max(p => p.Type.GetGenericTypeName().Length);
foreach (var p in verb.Parameters.OrderBy(p => p.Names.First()))
{
sb.Append(parametersLead);
sb.AppendFormat("/{0} : ",
p.Names.StringJoin(" /").ToLowerInvariant().PadRight(longestParameter, ' '));
if (!string.IsNullOrEmpty(p.Description))
{
sb.AppendFormat("{0} ", p.Description);
}
var typeName = GetTypeName(p.Type);
if (!string.IsNullOrEmpty(typeName))
{
sb.AppendFormat("({0}) ", typeName);
}
if (p.Required)
{
sb.Append("(Required) ");
}
if (p.Separator != null && p.Separator != SeparatorAttribute.DefaultSeparator)
{
sb.AppendFormat("(Separator = {0}) ", p.Separator);
}
if (p.Default != null)
{
sb.AppendFormat("(Default = {0}) ", p.Default);
}
if (p.Validations.Any())
{
sb.AppendFormat("({0}) ", p.Validations.StringJoin(", "));
}
sb.AppendLine();
} // foreach (var p in verb.Parameters
}
if (verb.Validations.Any())
{
sb.AppendLine();
sb.Append(parametersLead);
sb.AppendLine("Validation:");
foreach (var v in verb.Validations)
{
sb.Append(validationsLead);
sb.AppendLine(v);
}
}
} // foreach (var verb in parser.Verbs
if (parser.Globals.Any())
{
sb.AppendLine();
sb.Append(verbsLead);
sb.AppendLine("Global Parameters:");
var longestGlobal = parser.Globals.Max(p => p.Names.StringJoin("|").Length);
foreach (var g in parser.Globals.OrderBy(g => g.Names.First()))
{
sb.Append(parametersLead);
sb.AppendFormat("/{0} : ",
g.Names.StringJoin("|").ToLowerInvariant().PadRight(longestGlobal, ' '));
if (!string.IsNullOrEmpty(g.Description))
{
sb.AppendFormat("{0} ", g.Description);
}
var typeName = GetTypeName(g.Type);
if (!string.IsNullOrEmpty(typeName))
{
sb.AppendFormat("({0}) ", typeName);
}
if (g.Separator != null && g.Separator != SeparatorAttribute.DefaultSeparator)
{
sb.AppendFormat("(Separator = {0}) ", g.Separator);
}
if (g.Validations != null && g.Validations.Any())
{
sb.AppendFormat("({0}) ", g.Validations.StringJoin(", "));
}
sb.AppendLine();
} // foreach (var g in parser.Globals
}
if (multi && i < count - 1)
{
sb.AppendLine();
sb.Append(verbsLead);
sb.AppendLine(string.Empty.PadRight(80, '-'));
}
}
return sb.ToString();
}
private static string GetTypeName(Type type)
{
if (type.IsEnum)
{
return string.Format("{0} ({1})", type.Name, string.Join("/", Enum.GetNames(type)));
}
if (type == typeof(bool))
{
return string.Empty;
}
return type.GetGenericTypeName();
}
}
}
================================================
FILE: CLAP/DefaultProvider.cs
================================================
namespace CLAP
{
public abstract class DefaultProvider
{
public abstract object GetDefault(VerbExecutionContext context);
public virtual string Description
{
get
{
return GetType().Name;
}
}
}
}
================================================
FILE: CLAP/EmptyAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// Marks a method to be executed when there is no input.
/// The method must not accept any parameter except if marked along with [Help].
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class EmptyAttribute : Attribute
{
}
}
================================================
FILE: CLAP/EnvironmentParserHandlers.cs
================================================
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace CLAP
{
internal static class EnvironmentParserHandlers
{
internal static MultiParser Console(this MultiParser parser)
{
parser.Register.HelpHandler("help,h,?", help => System.Console.WriteLine(help));
parser.Register.ParameterHandler("debug", () => Debugger.Launch());
parser.Register.ErrorHandler(c => System.Console.Error.WriteLine(c.Exception.Message));
// a multi parser needs an empty help handler
//
if (parser.Types.Length > 1)
{
parser.Register.EmptyHelpHandler(help => System.Console.WriteLine(help));
}
return parser;
}
internal static MultiParser WinForms(this MultiParser parser)
{
parser.Register.HelpHandler("help,h,?", help => MessageBox.Show(help));
parser.Register.ParameterHandler("debug", () => Debugger.Launch());
parser.Register.ErrorHandler(c => MessageBox.Show(c.Exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error));
return parser;
}
}
}
================================================
FILE: CLAP/ErrorAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// Marks a method to be executed when an exception occurs.
/// The method may only accept one parameter of type CLAP.ExceptionContext
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ErrorAttribute : Attribute
{
}
}
================================================
FILE: CLAP/ExceptionContext.cs
================================================
using System;
namespace CLAP
{
public sealed class ExceptionContext
{
public Exception Exception { get; private set; }
public bool ReThrow { get; set; }
internal ExceptionContext(Exception ex)
{
Exception = ex;
}
}
}
================================================
FILE: CLAP/Exceptions.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
namespace CLAP
{
/// <summary>
/// Base exception class for all parser exceptions
/// </summary>
[Serializable]
public abstract class CommandLineParserException : Exception
{
/// <summary>
/// Constructor
/// </summary>
public CommandLineParserException() { }
/// <summary>
/// Constructor
/// </summary>
public CommandLineParserException(string message) : base(message) { }
/// <summary>
/// Constructor
/// </summary>
public CommandLineParserException(string message, Exception inner) : base(message, inner) { }
protected CommandLineParserException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MissingDefaultVerbException : CommandLineParserException
{
public MissingDefaultVerbException()
: this("No default verb was found")
{
}
public MissingDefaultVerbException(string message) : base(message) { }
public MissingDefaultVerbException(string message, Exception inner) : base(message, inner) { }
protected MissingDefaultVerbException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class VerbNotFoundException : CommandLineParserException
{
/// <summary>
/// The verb string that wasn't found
/// </summary>
public string Verb { get; private set; }
public VerbNotFoundException(string verb)
: base("Verb '{0}' was not found".FormatWith(verb))
{
Verb = verb;
}
public VerbNotFoundException(string message, Exception inner) : base(message, inner) { }
protected VerbNotFoundException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MissingVerbException : CommandLineParserException
{
public MissingVerbException()
: this("Arguments contain no verb", null)
{
}
public MissingVerbException(string message, Exception inner) : base(message, inner) { }
protected MissingVerbException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MultiParserMissingClassNameException : CommandLineParserException
{
public MultiParserMissingClassNameException()
: this("Arguments contain no class name nor verb", null)
{
}
public MultiParserMissingClassNameException(string message, Exception inner) : base(message, inner) { }
protected MultiParserMissingClassNameException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class InvalidVerbException : CommandLineParserException
{
public InvalidVerbException()
: this("Invalid verb", null)
{
}
public InvalidVerbException(string message, Exception inner) : base(message, inner) { }
protected InvalidVerbException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class UnknownParserTypeException : CommandLineParserException
{
public UnknownParserTypeException(string typeName)
: this("Parser type '{0}' not found".FormatWith(typeName), null)
{
}
public UnknownParserTypeException(string message, Exception inner) : base(message, inner) { }
protected UnknownParserTypeException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MissingRequiredArgumentException : CommandLineParserException
{
/// <summary>
/// The name of the required parameter
/// </summary>
public string ParameterName { get; private set; }
/// <summary>
/// The verb that requires the parameter
/// </summary>
public Method Method { get; private set; }
public MissingRequiredArgumentException(Method method, string parameter)
: base("Missing argument for required parameter '{0}'".FormatWith(parameter))
{
Method = method;
ParameterName = parameter;
}
public MissingRequiredArgumentException(string message, Exception inner) : base(message, inner) { }
protected MissingRequiredArgumentException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MissingArgumentValueException : CommandLineParserException
{
/// <summary>
/// The name of the parameter
/// </summary>
public string ParameterName { get; private set; }
public MissingArgumentValueException(string parameter)
: base("Parameter {0} has no input and is not a switch".FormatWith(parameter))
{
ParameterName = parameter;
}
public MissingArgumentValueException(string message, Exception inner) : base(message, inner) { }
protected MissingArgumentValueException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MissingArgumentPrefixException : CommandLineParserException
{
/// <summary>
/// The name of the parameter
/// </summary>
public string ParameterName { get; private set; }
public MissingArgumentPrefixException(string parameter, string prefixes)
: base("'{0}' should be prefixed with one of '{1}'".FormatWith(parameter, prefixes))
{
ParameterName = parameter;
}
public MissingArgumentPrefixException(string message, Exception inner) : base(message, inner) { }
protected MissingArgumentPrefixException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class ValidationException : CommandLineParserException
{
public ValidationException(string message) : base(message) { }
public ValidationException(string message, Exception inner) : base(message, inner) { }
protected ValidationException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class TypeConvertionException : CommandLineParserException
{
/// <summary>
/// The string value that failed to be converted
/// </summary>
public string Value { get; private set; }
/// <summary>
/// The target type
/// </summary>
public Type Type { get; private set; }
public TypeConvertionException(string value, Type type, Exception inner)
: base("'{0}' cannot be converted to {1}".FormatWith(value, type), inner)
{
Value = value;
Type = type;
}
protected TypeConvertionException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MoreThanOneEmptyHandlerException : CommandLineParserException
{
public MoreThanOneEmptyHandlerException()
: base("More than one empty handler was defined. Only a single method can be marked with [Empty] in a type and only a single action can be registered as an empty handler.")
{
}
protected MoreThanOneEmptyHandlerException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MoreThanOneErrorHandlerException : CommandLineParserException
{
public MoreThanOneErrorHandlerException()
: base("More than one error handler was defined. Only a single method can be marked with [Error] in a type and only a single action can be registered as an error handler.")
{
}
protected MoreThanOneErrorHandlerException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MoreThanOnePreVerbInterceptorException : CommandLineParserException
{
public MoreThanOnePreVerbInterceptorException()
: base("More than one pre-verb interceptor was defined. Only a single method can be marked with [PreVerbExecutionAttribute] in a type and only a single action can be registered as a pre-interceptor.")
{
}
protected MoreThanOnePreVerbInterceptorException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MoreThanOnePostVerbInterceptorException : CommandLineParserException
{
public MoreThanOnePostVerbInterceptorException()
: base("More than one post-verb interceptor was defined. Only a single method can be marked with [PostVerbExecutionAttribute] in a type and only a single action can be registered as a post-interceptor.")
{
}
protected MoreThanOnePostVerbInterceptorException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class ArgumentMismatchException : CommandLineParserException
{
public ArgumentMismatchException() { }
public ArgumentMismatchException(string message) : base(message) { }
public ArgumentMismatchException(string message, Exception inner) : base(message, inner) { }
protected ArgumentMismatchException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class ParserExecutionTargetException : CommandLineParserException
{
public ParserExecutionTargetException() { }
public ParserExecutionTargetException(string message) : base(message) { }
public ParserExecutionTargetException(string message, Exception inner) : base(message, inner) { }
protected ParserExecutionTargetException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class UnhandledParametersException : CommandLineParserException
{
/// <summary>
/// The collection of unhandled arguments
/// </summary>
public Dictionary<string, string> UnhandledParameters { get; private set; }
public UnhandledParametersException(Dictionary<string, string> unhandledParameters)
: base("Unhandled parameters: '{0}'".FormatWith(unhandledParameters.Keys.StringJoin(", ")))
{
UnhandledParameters = unhandledParameters;
}
protected UnhandledParametersException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class MoreThanOneDefaultVerbException : CommandLineParserException
{
/// <summary>
/// The collection of the verbs that are defined as default
/// </summary>
public IEnumerable<string> Verbs { get; private set; }
public MoreThanOneDefaultVerbException(IEnumerable<string> verbs)
: base("More than one default verb was defined: '{0}'".FormatWith(verbs.StringJoin(", ")))
{
Verbs = verbs;
}
protected MoreThanOneDefaultVerbException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class DuplicateTargetAliasException : CommandLineParserException
{
/// <summary>
/// The target alias that was determined to be duplicated.
/// </summary>
public string DuplicateTargetAlias { get; private set; }
public DuplicateTargetAliasException(string duplicateTargetAlias)
: base("TargetAlias value '{0}' has been specified more than once of the target types provided.".FormatWith(duplicateTargetAlias))
{
DuplicateTargetAlias = duplicateTargetAlias;
}
protected DuplicateTargetAliasException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class InvalidHelpHandlerException : CommandLineParserException
{
/// <summary>
/// The method that is defined as help
/// </summary>
public MethodInfo Method { get; private set; }
public InvalidHelpHandlerException(MethodInfo method)
: this(method, null)
{
}
public InvalidHelpHandlerException(MethodInfo method, Exception ex)
: base("Method '{0}' is marked as [Help] but it does not have a single string parameter".FormatWith(method.Name), ex)
{
Method = method;
}
protected InvalidHelpHandlerException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class AmbiguousParameterDefaultException : CommandLineParserException
{
/// <summary>
/// The parameter that has both a Default and a DefaultProvider
/// </summary>
public ParameterInfo Parameter { get; private set; }
public AmbiguousParameterDefaultException(ParameterInfo parameter)
: base("Parameter '{0}' of '{1}' has both a Default and a DefaultProvider".FormatWith(parameter.Name, parameter.Member.Name))
{
Parameter = parameter;
}
protected AmbiguousParameterDefaultException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class InvalidParameterDefaultProviderException : CommandLineParserException
{
/// <summary>
/// The parameter that has an invalid DefaultProvider
/// </summary>
public ParameterInfo Parameter { get; private set; }
public InvalidParameterDefaultProviderException(ParameterInfo parameter)
: base("Parameter '{0}' of '{1}' has an invalid DefaultProvider".FormatWith(parameter.Name, parameter.Member.Name))
{
Parameter = parameter;
}
protected InvalidParameterDefaultProviderException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class DuplicateGlobalHandlerException : CommandLineParserException
{
/// <summary>
/// The global handler name
/// </summary>
public string Name { get; private set; }
public DuplicateGlobalHandlerException(string name)
: base("Global parameter '{0}' is defined more than once".FormatWith(name))
{
Name = name;
}
protected DuplicateGlobalHandlerException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class NonArrayParameterWithSeparatorException : CommandLineParserException
{
/// <summary>
/// The parameter
/// </summary>
public ParameterInfo Parameter { get; private set; }
public NonArrayParameterWithSeparatorException(ParameterInfo parameter)
: base("Parameter '{0}' of '{1}' is marked with [{2}] but it is not an array".FormatWith(
parameter.Name,
parameter.Member.Name,
typeof(SeparatorAttribute).Name))
{
Parameter = parameter;
}
protected NonArrayParameterWithSeparatorException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class InvalidSeparatorException : CommandLineParserException
{
/// <summary>
/// The parameter
/// </summary>
public ParameterInfo Parameter { get; private set; }
public InvalidSeparatorException(ParameterInfo parameter)
: base("Parameter '{0}' of '{1}' has an invalid separator. A separator cannot be empty or contain spaces.".FormatWith(
parameter.Name,
parameter.Member.Name))
{
Parameter = parameter;
}
protected InvalidSeparatorException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
}
================================================
FILE: CLAP/FW2Stuff.cs
================================================
#if FW2
using System;
using System.Collections;
using System.Collections.Generic;
namespace CLAP
{
#region Delegates
public delegate void Action();
public delegate void Action<T>(T arg);
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
#endregion Delegates
#region Enumerable
internal static class Enumerable
{
public static IEnumerable<T> Cast<T>(this IEnumerable collection)
{
foreach (var item in collection)
{
yield return (T)item;
}
}
public static IEnumerable<T> Where<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (predicate(item))
{
yield return item;
}
}
}
public static T First<T>(this IEnumerable<T> collection)
{
foreach (var item in collection)
{
return item;
}
throw new InvalidOperationException("No elements in the collection that matches the predicate");
}
public static T First<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (predicate(item))
{
return item;
}
}
throw new InvalidOperationException("No elements in the collection that matches the predicate");
}
public static T FirstOrDefault<T>(this IEnumerable<T> collection)
{
foreach (var item in collection)
{
return item;
}
return default(T);
}
public static T FirstOrDefault<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (predicate(item))
{
return item;
}
}
return default(T);
}
public static bool Any<T>(this IEnumerable<T> collection)
{
foreach (var item in collection)
{
return true;
}
return false;
}
public static bool Any<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (predicate(item))
{
return true;
}
}
return false;
}
public static bool All<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (!predicate(item))
{
return false;
}
}
return true;
}
public static int Count<T>(this IEnumerable<T> collection)
{
var c = 0;
foreach (var item in collection)
{
c++;
}
return c;
}
public static int Count<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
var c = 0;
foreach (var item in collection)
{
if (predicate(item))
{
c++;
}
}
return c;
}
public static T[] ToArray<T>(this IEnumerable<T> collection)
{
var arr = new T[collection.Count()];
var i = 0;
foreach (var item in collection)
{
arr[i] = item;
i++;
}
return arr;
}
public static IEnumerable<TItem> OrderBy<TItem, TResult>(
this IEnumerable<TItem> collection,
Func<TItem, TResult> func)
{
var items = collection.ToArray();
var keysList = new List<TResult>();
foreach (var item in collection)
{
keysList.Add(func(item));
}
var keys = keysList.ToArray();
Array.Sort(keys, items);
return items;
}
public static IEnumerable<TItem> OrderByDescending<TItem, TResult>(
this IEnumerable<TItem> collection,
Func<TItem, TResult> func)
{
var arr = OrderBy(collection, func).ToArray();
Array.Reverse(arr);
return arr;
}
public static IEnumerable<T> Skip<T>(this IEnumerable<T> collection, int count)
{
foreach (var item in collection)
{
count--;
if (count >= 0)
{
continue;
}
yield return item;
}
}
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> collection,
Func<TSource, TResult> selector)
{
foreach (var item in collection)
{
yield return selector(item);
}
}
public static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> collection,
Func<TSource, IEnumerable<TResult>> selector)
{
foreach (var item in collection)
{
var innerItems = selector(item);
foreach (var innerItem in innerItems)
{
yield return innerItem;
}
}
}
public static IEnumerable<T> Distinct<T>(this IEnumerable<T> collection)
{
var list = new List<T>();
foreach (var item in collection)
{
if (!list.Contains(item))
{
list.Add(item);
yield return item;
}
}
}
public static IEnumerable<TSource> Union<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second)
{
foreach (var item in first)
{
yield return item;
}
foreach (var item in second)
{
yield return item;
}
}
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value)
{
foreach (var item in source)
{
if (object.Equals(item, value))
{
return true;
}
}
return false;
}
public static List<T> ToList<T>(this IEnumerable<T> collection)
{
var list = new List<T>();
foreach (var item in collection)
{
list.Add(item);
}
return list;
}
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector)
{
var dict = new Dictionary<TKey, TElement>();
foreach (var item in source)
{
dict.Add(keySelector(item), elementSelector(item));
}
return dict;
}
public static int Max<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
int? max = null;
foreach (var item in source)
{
var v = selector(item);
if (!max.HasValue || v > max)
{
max = v;
}
}
return max.Value;
}
}
#endregion Enumerable
}
namespace System.Runtime.CompilerServices
{
internal class ExtensionAttribute : Attribute
{
}
}
#endif
================================================
FILE: CLAP/FileSystemHelper.cs
================================================
using System.IO;
namespace CLAP
{
/// <summary>
/// A helper for file reading to allow mocking for tests
/// </summary>
public static class FileSystemHelper
{
public static IFileSystem FileHandler { get; set; }
static FileSystemHelper()
{
FileHandler = new FileSystem();
}
internal static string ReadAllText(string path)
{
return FileHandler.ReadAllText(path);
}
public interface IFileSystem
{
string ReadAllText(string path);
}
[CoverageExclude]
private class FileSystem : IFileSystem
{
public string ReadAllText(string path)
{
return File.ReadAllText(path);
}
}
}
}
================================================
FILE: CLAP/GlobalAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// Marks a method as a global parameter.
/// The method can either accept any single allowed parameter type or accept
/// no parameters and be treated as a boolean switch.
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class GlobalAttribute : Attribute
{
/// <summary>
/// The additional aliases (as CSV) of the parameter
/// </summary>
public string Aliases { get; set; }
/// <summary>
/// The description of this parameter
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// The name of this parameter
/// </summary>
public string Name { get; private set; }
public GlobalAttribute()
: this(null)
{
}
public GlobalAttribute(string name)
{
Aliases = string.Empty;
Name = name;
}
}
}
================================================
FILE: CLAP/HelpAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// Marks a method to be called when the user asks for help
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class HelpAttribute : Attribute
{
/// <summary>
/// The additional aliases (as CSV) of the parameter
/// </summary>
public string Aliases { get; set; }
/// <summary>
/// The name of this parameter
/// </summary>
public string Name { get; private set; }
public HelpAttribute()
: this(null)
{
}
public HelpAttribute(string name)
{
Aliases = string.Empty;
Name = name;
}
}
}
================================================
FILE: CLAP/HelpGeneratorBase.cs
================================================
using System.Collections.Generic;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
public abstract class HelpGeneratorBase
{
internal string GetHelp(ParserRunner parser)
{
return GetHelp(new[] { parser });
}
internal string GetHelp(IEnumerable<ParserRunner> parsers)
{
var help = new HelpInfo {Parsers = parsers.Select(GetParserHelp).ToList()};
var helpString = GetHelpString(help);
return helpString;
}
protected abstract string GetHelpString(HelpInfo helpInfo);
private static ParserHelpInfo GetParserHelp(ParserRunner parser)
{
var h = new ParserHelpInfo
{
Type = parser.Type,
Verbs = parser.GetVerbs().Select(verb => new VerbHelpInfo
{
Names = verb.Names.OrderByDescending(n => n.Length).ToList(),
Description = verb.Description,
IsDefault = verb.IsDefault,
Validations = verb.MethodInfo.GetInterfaceAttributes<ICollectionValidation>().Select(v => v.Description).ToList(),
Parameters = ParserRunner.GetParameters(verb.MethodInfo).
Select(p => new ParameterHelpInfo
{
Required = p.Required,
Names = p.Names.OrderBy(n => n.Length).ToList(),
Type = p.ParameterInfo.ParameterType,
Default = p.DefaultProvider != null ? p.DefaultProvider.Description : p.Default,
Description = p.Description,
Validations = p.ParameterInfo.GetAttributes<ValidationAttribute>().Select(v => v.Description).ToList(),
Separator = p.ParameterInfo.ParameterType.IsArray ?
p.Separator ?? SeparatorAttribute.DefaultSeparator : null,
}).ToList(),
}).ToList(),
Globals = parser.GetDefinedGlobals().Select(g =>
{
var att = g.GetAttribute<GlobalAttribute>();
var parameter = ParserRunner.GetParameters(g).FirstOrDefault();
return new GlobalParameterHelpInfo
{
Names = att.Aliases.CommaSplit().Union(new[] { att.Name ?? g.Name }).OrderBy(n => n.Length).ToList(),
Type = parameter != null ? parameter.ParameterInfo.ParameterType : typeof(bool),
Description = att.Description,
Validations = g.GetInterfaceAttributes<ICollectionValidation>().Select(v => v.Description).ToList(),
Separator = parameter != null ?
parameter.ParameterInfo.ParameterType.IsArray ?
parameter.Separator ?? SeparatorAttribute.DefaultSeparator :
null : null,
};
}).Union(parser.Register.RegisteredGlobalHandlers.Values.Select(handler => new GlobalParameterHelpInfo
{
Names = handler.Names.OrderBy(n => n.Length).ToList(),
Type = handler.Type,
Description = handler.Description,
Validations = new List<string>(),
})).ToList(),
};
if (parser.Register.RegisteredHelpHandlers.Any())
{
h.Globals.Add(new GlobalParameterHelpInfo
{
Names = parser.Register.RegisteredHelpHandlers.Keys.ToList(),
Type = typeof(bool),
Description = "Help",
});
}
return h;
}
}
}
================================================
FILE: CLAP/HelpInfo.cs
================================================
using System;
using System.Collections.Generic;
namespace CLAP
{
public class HelpInfo
{
public List<ParserHelpInfo> Parsers { get; set; }
}
public class ParserHelpInfo
{
public Type Type { get; set; }
public List<VerbHelpInfo> Verbs { get; set; }
public List<GlobalParameterHelpInfo> Globals { get; set; }
}
public class VerbHelpInfo
{
public bool IsDefault { get; set; }
public string Description { get; set; }
public List<string> Names { get; set; }
public List<ParameterHelpInfo> Parameters { get; set; }
public List<string> Validations { get; set; }
}
public class ParameterHelpInfo
{
public bool Required { get; set; }
public List<string> Names { get; set; }
public List<string> Validations { get; set; }
public Type Type { get; set; }
public object Default { get; set; }
public string Description { get; set; }
public string Separator { get; set; }
}
public class GlobalParameterHelpInfo
{
public List<string> Names { get; set; }
public List<string> Validations { get; set; }
public Type Type { get; set; }
public string Description { get; set; }
public string Separator { get; set; }
}
}
================================================
FILE: CLAP/IValidation.cs
================================================
namespace CLAP
{
/// <summary>
/// Validation of collections of parameters and values
/// </summary>
public interface ICollectionValidation
{
/// <summary>
/// Gets an instance of the collection validator
/// </summary>
/// <returns></returns>
ICollectionValidator GetValidator();
/// <summary>
/// The description of this validation attribute, used when asking for help
/// </summary>
string Description { get; }
}
/// <summary>
/// Validation of collections of parameters and values
/// </summary>
public interface ICollectionValidator
{
void Validate(ValueInfo[] properties);
}
}
================================================
FILE: CLAP/Interception/IVerbInterceptor.cs
================================================
namespace CLAP.Interception
{
/// <summary>
/// Gives interception options to verb execution
/// </summary>
public interface IVerbInterceptor : IPreVerbInterceptor, IPostVerbInterceptor
{
}
/// <summary>
/// Gives interception options to verb execution BEFORE the verb is executed
/// </summary>
public interface IPreVerbInterceptor
{
void BeforeVerbExecution(PreVerbExecutionContext context);
}
/// <summary>
/// Gives interception options to verb execution AFTER the verb is executed, even if the execution fails
/// </summary>
public interface IPostVerbInterceptor
{
void AfterVerbExecution(PostVerbExecutionContext context);
}
}
================================================
FILE: CLAP/Interception/ParameterAndValue.cs
================================================
namespace CLAP.Interception
{
/// <summary>
/// A parameter and its value
/// </summary>
public sealed class ParameterAndValue
{
/// <summary>
/// The parameter
/// </summary>
public Parameter Parameter { get; private set; }
/// <summary>
/// The value of the parameter
/// </summary>
public object Value { get; private set; }
internal ParameterAndValue(Parameter parameter, object value)
{
Parameter = parameter;
Value = value;
}
}
}
================================================
FILE: CLAP/Interception/PostVerbExecutionAttribute.cs
================================================
using System;
namespace CLAP.Interception
{
/// <summary>
/// Marks a method to run after each verb is executed
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class PostVerbExecutionAttribute : Attribute
{
}
}
================================================
FILE: CLAP/Interception/PostVerbExecutionContext.cs
================================================
using System;
using System.Collections.Generic;
namespace CLAP.Interception
{
/// <summary>
/// The context after a verb was executed
/// </summary>
public sealed class PostVerbExecutionContext : UserVerbExecutionContext
{
#region Properties
/// <summary>
/// Whether the verb execution was cancelled by the pre-execution interception
/// </summary>
public bool Cancelled { get; private set; }
/// <summary>
/// If the verb failed to execute - this contains the exception that was thrown
/// </summary>
public Exception Exception { get; private set; }
/// <summary>
/// Whether the verb failed to execute
/// </summary>
public bool Failed
{
get { return Exception != null; }
}
#endregion Properties
#region Constructors
internal PostVerbExecutionContext(
Method method,
object target,
ParameterAndValue[] parameters,
bool cancelled,
Exception exception,
Dictionary<object, object> userContext)
: base(method, target, parameters, userContext)
{
Cancelled = cancelled;
Exception = exception;
}
#endregion Constructors
}
}
================================================
FILE: CLAP/Interception/PreVerbExecutionAttribute.cs
================================================
using System;
namespace CLAP.Interception
{
/// <summary>
/// Marks a method to run before each verb is executed
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class PreVerbExecutionAttribute : Attribute
{
}
}
================================================
FILE: CLAP/Interception/PreVerbExecutionContext.cs
================================================
using System.Collections.Generic;
namespace CLAP.Interception
{
/// <summary>
/// The context before a verb is to be executed
/// </summary>
public sealed class PreVerbExecutionContext : UserVerbExecutionContext
{
#region Properties
/// <summary>
/// Whether to cancel to verb execution.
/// The post-interception will be called having the Cancelled property set to true.
/// </summary>
public bool Cancel { get; set; }
#endregion Properties
#region Constructors
internal PreVerbExecutionContext(
Method method,
object target,
ParameterAndValue[] parameters)
: base(method, target, parameters, new Dictionary<object, object>())
{
}
#endregion Constructors
}
}
================================================
FILE: CLAP/Interception/UserVerbExecutionContext.cs
================================================
using System.Collections.Generic;
namespace CLAP.Interception
{
public abstract class UserVerbExecutionContext
{
/// <summary>
/// The method that is executed
/// </summary>
public Method Method { get; private set; }
/// <summary>
/// The target object, if any, that the verb is executed on.
/// If the verb is static, this is null.
/// </summary>
public object Target { get; private set; }
/// <summary>
/// A user-context that can be filled with custom keys and values.
/// Once filled in the pre-execution context - it is available in the post-execution context.
/// </summary>
public Dictionary<object, object> UserContext { get; private set; }
/// <summary>
/// The list of parameters and their values
/// </summary>
public ParameterAndValue[] Parameters { get; private set; }
protected UserVerbExecutionContext(
Method method,
object target,
ParameterAndValue[] parameters,
Dictionary<object, object> userContext)
{
Method = method;
Target = target;
Parameters = parameters;
UserContext = userContext;
}
}
}
================================================
FILE: CLAP/Interception/VerbInterception.cs
================================================
using System;
namespace CLAP.Interception
{
/// <summary>
/// Marks a class to allow verb-interception by a defined IVerbInterceptor
/// (or either IPreVerbInterceptor or IPostVerbInterceptor) type
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class VerbInterception : Attribute
{
/// <summary>
/// The interceptor type
/// </summary>
public Type InterceptorType { get; private set; }
/// <summary>
/// Marks a class to allow verb-interception by a defined IVerbInterceptor
/// (or either IPreVerbInterceptor or IPostVerbInterceptor) type
/// </summary>
/// <param name="interceptorType">An interceptor type that implements either IVerbInterceptor, IPreVerbInterceptor or IPostVerbInterceptor</param>
public VerbInterception(Type interceptorType)
{
InterceptorType = interceptorType;
}
}
}
================================================
FILE: CLAP/Method.cs
================================================
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
namespace CLAP
{
/// <summary>
/// A method descriptor
/// </summary>
[DebuggerDisplay("{MethodInfo}")]
public sealed class Method
{
#region Properties
/// <summary>
/// The names of the method, as defined by the Verb attribute and the additional names
/// </summary>
public List<string> Names { get; private set; }
/// <summary>
/// The description of the method
/// </summary>
public string Description { get; private set; }
/// <summary>
/// The <see cref="MethodInfo"/> this method describes
/// </summary>
public MethodInfo MethodInfo { get; private set; }
/// <summary>
/// Whether this verb is the default verb of the class
/// </summary>
public bool IsDefault { get; set; }
#endregion Properties
#region Constructors
internal Method(MethodInfo method)
{
Debug.Assert(method != null);
Names = new List<string>();
// Names are stored as lower-case.
// The first available name is the method's original name.
//
Names.Add(method.Name.ToLowerInvariant());
MethodInfo = method;
var verbAttribute = method.GetAttribute<VerbAttribute>();
Description = verbAttribute.Description;
IsDefault = verbAttribute.IsDefault;
if (verbAttribute.Aliases != null)
{
Names.AddRange(verbAttribute.Aliases.ToLowerInvariant().CommaSplit());
}
}
#endregion Constructors
}
}
================================================
FILE: CLAP/MethodInvoker.cs
================================================
using System.Diagnostics;
using System.Reflection;
namespace CLAP
{
/// <summary>
/// A helper for method invoking to allow mocking for tests
/// </summary>
public static class MethodInvoker
{
public static IMethodInvoker Invoker { get; set; }
static MethodInvoker()
{
Invoker = new DefaultMethodInvoker();
}
public static void Invoke(MethodInfo method, object obj, object[] parameters)
{
Debug.Assert(method != null);
Invoker.Invoke(method, obj, parameters);
}
private class DefaultMethodInvoker : IMethodInvoker
{
public void Invoke(MethodInfo method, object obj, object[] parameters)
{
method.Invoke(obj, parameters);
}
}
}
public interface IMethodInvoker
{
void Invoke(MethodInfo method, object obj, object[] parameters);
}
}
================================================
FILE: CLAP/MultiParser.cs
================================================
using System;
using System.Diagnostics;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
/// <summary>
/// A parser of one or more classes
/// </summary>
public abstract class MultiParser
{
#region Fields
private static readonly string[] s_delimiters = new[] { ".", "/" };
private readonly Type[] m_types;
public HelpGeneratorBase HelpGenerator = new DefaultHelpGenerator();
internal const int ErrorCode = 1;
internal const int SuccessCode = 0;
#endregion Fields
#region Properties
internal Type[] Types
{
get { return m_types; }
}
/// <summary>
/// Parser registration
/// </summary>
public ParserRegistration Register { get; private set; }
#endregion Properties
#region Constructors
protected MultiParser(params Type[] types)
{
m_types = types;
Init();
}
protected MultiParser()
{
m_types = GetType().GetGenericArguments();
Init();
}
#endregion Constructors
#region Private Methods
private void Init()
{
Debug.Assert(m_types.Any());
Register = new ParserRegistration(m_types, GetHelpString);
foreach (var type in m_types)
{
ParserRunner.Validate(type, Register);
}
}
private void HandleEmptyArguments(TargetResolver targetResolver)
{
if (Register.RegisteredEmptyHandler != null)
{
Register.RegisteredEmptyHandler();
}
else if (m_types.Length == 1)
{
var parser = new ParserRunner(m_types.First(), Register, HelpGenerator);
var target = targetResolver == null ? null : targetResolver.Resolve(m_types[0]);
parser.HandleEmptyArguments(target);
}
}
private ParserRunner GetMultiTypesParser(string[] args, ParserRegistration registration)
{
Debug.Assert(args.Any());
var verb = args[0];
// if the first arg is not a verb - throw
//
if (verb.StartsWith(ParserRunner.ArgumentPrefixes))
{
throw new MissingVerbException();
}
if (!verb.Contains(s_delimiters))
{
throw new MultiParserMissingClassNameException();
}
var parts = verb.Split(s_delimiters, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
{
throw new InvalidVerbException();
}
var typeNameOrAlias = parts[0];
args[0] = args[0].Substring(typeNameOrAlias.Length + 1);
var matchingType = registration.GetTargetType(typeNameOrAlias);
if (matchingType == null)
{
throw new UnknownParserTypeException(typeNameOrAlias);
}
return new ParserRunner(matchingType, registration, HelpGenerator); }
private ParserRunner GetSingleTypeParser(string[] args, ParserRegistration registration)
{
Debug.Assert(m_types.Length == 1);
var type = m_types.First();
var verb = args[0];
var parser = new ParserRunner(type, registration, HelpGenerator);
// if there is no verb - leave all the args as is
//
if (verb.StartsWith(ParserRunner.ArgumentPrefixes))
{
return parser;
}
// if the verb contains a delimiter - remove the type name from the arg
//
if (verb.Contains(s_delimiters))
{
var parts = verb.Split(s_delimiters, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
{
throw new InvalidVerbException();
}
Debug.Assert(parts.Length == 2);
var typeName = parts[0];
if (!type.Name.Equals(typeName, StringComparison.InvariantCultureIgnoreCase))
{
throw new UnknownParserTypeException(typeName);
}
args[0] = args[0].Substring(typeName.Length + 1);
}
return parser;
}
#endregion Private Methods
#region Public Methods
/// <summary>
/// Run a parser of static verbs
/// </summary>
/// <param name="args">The user arguments</param>
public int RunStatic(string[] args)
{
return RunTargets(args, null as TargetResolver);
}
/// <summary>
/// Run a parser of instance verbs against instances of the verb classes
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="targets">The instances of the verb classes</param>
public int RunTargets(string[] args, params object[] targets)
{
var targetResolver = new TargetResolver(targets);
return RunTargets(args, targetResolver);
}
public int RunTargets(string[] args, TargetResolver targetResolver)
{
ParserRunner parser;
try
{
if (args.None() || args.All(a => string.IsNullOrEmpty(a)))
{
HandleEmptyArguments(targetResolver);
return SuccessCode;
}
if (m_types.Length == 1)
{
parser = GetSingleTypeParser(args, Register);
}
else
{
Debug.Assert(m_types.Length > 1);
parser = GetMultiTypesParser(args, Register);
}
Debug.Assert(parser != null);
}
catch (Exception ex)
{
// handle error using the first available error handler
//
// (if returns true - should rethrow)
//
if (TryHandlePrematureError(ex, targetResolver))
{
throw;
}
else
{
return ErrorCode;
}
}
var target = (targetResolver == null || targetResolver.RegisteredTypes.None()) ? null : targetResolver.Resolve(parser.Type);
return parser.Run(args, target);
}
private bool TryHandlePrematureError(Exception ex, TargetResolver targetResolver)
{
var context = new ExceptionContext(ex);
if (Register.RegisteredErrorHandler != null)
{
Register.RegisteredErrorHandler(context);
return context.ReThrow;
}
else
{
for (int i = 0; i < m_types.Length; i++)
{
var type = m_types[i];
var errorHandler = ParserRunner.GetDefinedErrorHandlers(type).FirstOrDefault();
if (errorHandler != null)
{
var target = targetResolver == null ? null : targetResolver.Resolve(type);
errorHandler.Invoke(target, new[] { context });
return context.ReThrow;
}
}
}
return true;
}
/// <summary>
/// Gets a help string that describes all the parser information for the user
/// </summary>
public string GetHelpString()
{
return HelpGenerator.GetHelp(Types.Select(t => new ParserRunner(t, Register, HelpGenerator)));
}
#endregion Public Methods
}
}
================================================
FILE: CLAP/Pair.cs
================================================
namespace CLAP
{
internal class Pair<TFirst, TSecond>
{
public TFirst First { get; private set; }
public TSecond Second { get; private set; }
public Pair(TFirst first, TSecond second)
{
First = first;
Second = second;
}
}
internal static class Pair
{
internal static Pair<TFirst, TSecond> Create<TFirst, TSecond>(TFirst first, TSecond second)
{
return new Pair<TFirst, TSecond>(first, second);
}
}
}
================================================
FILE: CLAP/Parameter.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
namespace CLAP
{
/// <summary>
/// A parameter descriptor
/// </summary>
[DebuggerDisplay("{ParameterInfo}")]
public sealed class Parameter
{
#region Properties
/// <summary>
/// The default value
/// </summary>
public object Default { get; private set; }
/// <summary>
/// The default value provider
/// </summary>
public DefaultProvider DefaultProvider { get; private set; }
/// <summary>
/// Whether this parameter is required
/// </summary>
public Boolean Required { get; private set; }
/// <summary>
/// The names of the parameter, as defined by the Parameter attribute and the additional names
/// </summary>
public List<string> Names { get; private set; }
/// <summary>
/// The parameter description
/// </summary>
public string Description { get; private set; }
/// <summary>
/// The parameter array separator
/// </summary>
public string Separator { get; private set; }
/// <summary>
/// The <see cref="ParameterInfo"/> this parameter describes
/// </summary>
public ParameterInfo ParameterInfo { get; private set; }
#endregion Properties
#region Constructors
internal Parameter(ParameterInfo parameter)
{
Debug.Assert(parameter != null);
Names = new List<string>();
// Names are stored as lower-case.
// The first available name is the parameters's original name.
//
Names.Add(parameter.Name.ToLowerInvariant());
ParameterInfo = parameter;
Required = parameter.HasAttribute<RequiredAttribute>();
if (parameter.HasAttribute<DefaultValueAttribute>())
{
Default = parameter.GetAttribute<DefaultValueAttribute>().DefaultValue;
}
if (parameter.HasAttribute<DefaultProviderAttribute>())
{
DefaultProvider = (DefaultProvider)Activator.CreateInstance(
parameter.GetAttribute<DefaultProviderAttribute>().DefaultProviderType);
}
if (parameter.HasAttribute<DescriptionAttribute>())
{
Description = parameter.GetAttribute<DescriptionAttribute>().Description;
}
if (parameter.HasAttribute<AliasesAttribute>())
{
Names.AddRange(parameter.GetAttribute<AliasesAttribute>().Aliases.ToLowerInvariant().CommaSplit());
}
if (parameter.HasAttribute<SeparatorAttribute>())
{
Separator = parameter.GetAttribute<SeparatorAttribute>().Separator;
}
}
#endregion Constructors
}
}
================================================
FILE: CLAP/ParameterAttribute.cs
================================================
using System;
namespace CLAP
{
/// <summary>
/// A parameter
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
[Obsolete("Use DefaultValueAttribute, DefaultProviderAttribute, RequiredAttribute, AliasesAttribute and DescriptionAttribute")]
public sealed class ParameterAttribute : Attribute
{
/// <summary>
/// The default value
/// </summary>
[Obsolete("Use DefaultValueAttribute")]
public object Default { get; set; }
/// <summary>
/// The default provider type
/// </summary>
/// <remarks>
/// The type must derive from CLAP.DefaultProvider.
/// A parameter cannot have both a Default and a DefaultProvider defined.
/// </remarks>
[Obsolete("Use DefaultProviderAttribute")]
public Type DefaultProvider { get; set; }
/// <summary>
/// Whether this parameter is required
/// </summary>
[Obsolete("Use RequiredAttribute")]
public Boolean Required { get; set; }
/// <summary>
/// The parameter additional names
/// </summary>
[Obsolete("Use AliasesAttribute")]
public string Aliases { get; set; }
/// <summary>
/// The description of the verb. Used to generate the help string
/// </summary>
[Obsolete("Use DescriptionAttribute")]
public string Description { get; set; }
}
/// <summary>
/// Sets a default value for a parameter
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultValueAttribute : Attribute
{
public object DefaultValue { get; private set; }
public DefaultValueAttribute(object defaultValue)
{
DefaultValue = defaultValue;
}
}
/// <summary>
/// Sets a default value provider type for a parameter.
/// The type must derive from DefaultProvider
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultProviderAttribute : Attribute
{
public Type DefaultProviderType { get; private set; }
public DefaultProviderAttribute(Type defaultProviderType)
{
DefaultProviderType = defaultProviderType;
}
}
/// <summary>
/// Marks a parameter to be required
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class RequiredAttribute : Attribute
{
}
/// <summary>
/// Sets additional names to a parameter
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AliasesAttribute : Attribute
{
public string Aliases { get; private set; }
public AliasesAttribute(string aliases)
{
Aliases = aliases;
}
}
/// <summary>
/// Sets a description to a parameter
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public class DescriptionAttribute : Attribute
{
public virtual string Description { get; private set; }
public DescriptionAttribute(string description)
{
Description = description;
}
}
/// <summary>
/// Sets an array parameter separator
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class SeparatorAttribute : Attribute
{
public string Separator { get; private set; }
public const string DefaultSeparator = ",";
/// <summary>
/// The separator to use.
/// The default is a comma (",")
/// </summary>
/// <param name="separator"></param>
public SeparatorAttribute(string separator)
{
Separator = separator;
}
}
}
================================================
FILE: CLAP/ParametersExpressionValidator.cs
================================================
using System.Data;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
/// <summary>
/// Validates a collection of named parameters or properties against a boolean expression
/// </summary>
internal class ParametersExpressionValidator : ICollectionValidator
{
/// <summary>
/// The expression
/// </summary>
public string Expression { get; private set; }
/// <summary>
/// Whether the expression should be treated as case-sensitive
/// </summary>
public bool CaseSensitive { get; private set; }
internal ParametersExpressionValidator(string expression, bool caseSensitive)
{
Expression = expression;
CaseSensitive = caseSensitive;
}
public void Validate(ValueInfo[] parameters)
{
var table = new DataTable();
table.CaseSensitive = CaseSensitive;
// create a column for each parameter giving its name and type
//
table.Columns.AddRange(
parameters.Select(
p => new DataColumn(
p.Name,
p.Type)).ToArray());
// create one row with all the values
//
table.Rows.Add(parameters.Select(p => p.Value).ToArray());
// run the expression
//
var selected = table.Select(Expression);
if (!selected.Any())
{
throw new ValidationException("Expression failed validation: '{0}' for arguments: [{1}]".FormatWith(
Expression,
parameters.Select(
p => "{0}={1}".FormatWith(
p.Name,
p.Value.ToSafeString("<NULL>"))).StringJoin(", ")));
}
}
}
}
================================================
FILE: CLAP/Parser.Console.cs
================================================
using System.Diagnostics;
using System.Linq;
namespace CLAP
{
public partial class Parser
{
/// <summary>
/// Executes a console parser of instance-verbs based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="targets">The instances of the verb classes</param>
public static int RunConsole(string[] args, params object[] targets)
{
Debug.Assert(targets.Any());
Debug.Assert(targets.All(t => t != null));
var p = new Parser(targets.Select(t => t.GetType()).ToArray()).Console();
return ((MultiParser)p).RunTargets(args, targets);
}
/// <summary>
/// Executes a generic console static parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
public static int RunConsole<T>(string[] args)
{ return new Parser<T>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t">An instance of the verb class</param>
public static int RunConsole<T>(string[] args, T t)
{ return new Parser<T>().Console().RunTargets(args, t); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2>(string[] args)
{ return new Parser<T1, T2>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
public static int RunConsole<T1, T2>(string[] args, T1 t1, T2 t2)
{ return new Parser<T1, T2>().Console().RunTargets(args, t1, t2); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3>(string[] args)
{ return new Parser<T1, T2, T3>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3>(string[] args, T1 t1, T2 t2, T3 t3)
{ return new Parser<T1, T2, T3>().Console().RunTargets(args, t1, t2, t3); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4>(string[] args)
{ return new Parser<T1, T2, T3, T4>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4)
{ return new Parser<T1, T2, T3, T4>().Console().RunTargets(args, t1, t2, t3, t4); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4, T5>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4, T5>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{ return new Parser<T1, T2, T3, T4, T5>().Console().RunTargets(args, t1, t2, t3, t4, t5); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{ return new Parser<T1, T2, T3, T4, T5, T6>().Console().RunTargets(args, t1, t2, t3, t4, t5, t6); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().Console().RunTargets(args, t1, t2, t3, t4, t5, t6, t7); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().Console().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8); }
/// <summary>
/// Executes a generic console static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().Console().RunStatic(args); }
/// <summary>
/// Executes a generic console parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <typeparam name="T9">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
/// <param name="t9">An instance of the verb class</param>
public static int RunConsole<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().Console().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8, t9); }
}
}
================================================
FILE: CLAP/Parser.WinForms.cs
================================================
using System.Diagnostics;
using System.Linq;
namespace CLAP
{
public partial class Parser
{
/// <summary>
/// Executes a winforms parser of instance-verbs based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="targets">The instances of the verb classes</param>
public static int RunWinForms(string[] args, params object[] targets)
{
Debug.Assert(targets.Any());
Debug.Assert(targets.All(t => t != null));
var p = new Parser(targets.Select(t => t.GetType()).ToArray()).WinForms();
return ((MultiParser)p).RunTargets(args, targets);
}
/// <summary>
/// Executes a generic winforms static parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T>(string[] args)
{ return new Parser<T>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t">An instance of the verb class</param>
public static int RunWinForms<T>(string[] args, T t)
{ return new Parser<T>().WinForms().RunTargets(args, t); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2>(string[] args)
{ return new Parser<T1, T2>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
public static int RunWinForms<T1, T2>(string[] args, T1 t1, T2 t2)
{ return new Parser<T1, T2>().WinForms().RunTargets(args, t1, t2); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3>(string[] args)
{ return new Parser<T1, T2, T3>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3>(string[] args, T1 t1, T2 t2, T3 t3)
{ return new Parser<T1, T2, T3>().WinForms().RunTargets(args, t1, t2, t3); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4>(string[] args)
{ return new Parser<T1, T2, T3, T4>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4)
{ return new Parser<T1, T2, T3, T4>().WinForms().RunTargets(args, t1, t2, t3, t4); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4, T5>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4, T5>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{ return new Parser<T1, T2, T3, T4, T5>().WinForms().RunTargets(args, t1, t2, t3, t4, t5); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{ return new Parser<T1, T2, T3, T4, T5, T6>().WinForms().RunTargets(args, t1, t2, t3, t4, t5, t6); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().WinForms().RunTargets(args, t1, t2, t3, t4, t5, t6, t7); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().WinForms().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8); }
/// <summary>
/// Executes a generic winforms static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().WinForms().RunStatic(args); }
/// <summary>
/// Executes a generic winforms parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <typeparam name="T9">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
/// <param name="t9">An instance of the verb class</param>
public static int RunWinForms<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().WinForms().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8, t9); }
}
}
================================================
FILE: CLAP/Parser.cs
================================================
using System;
using System.Diagnostics;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
/// <summary>
/// A command-line arguments parser
/// </summary>
public partial class Parser : MultiParser
{
/// <summary>
/// Creates a parser based on the specified types
/// </summary>
/// <param name="types"></param>
public Parser(params Type[] types)
: base(types)
{
}
/// <summary>
/// Executes a parser of instance-verbs based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="targets">The instances of the verb classes</param>
public static int Run(string[] args, params object[] targets)
{
Debug.Assert(targets.Any());
Debug.Assert(targets.All(t => t != null));
var p = new Parser(targets.Select(t => t.GetType()).ToArray());
return ((MultiParser)p).RunTargets(args, targets);
}
public static int Run(string[] args, TargetResolver targetResolver)
{
Debug.Assert(targetResolver != null);
var p = new Parser(targetResolver.RegisteredTypes);
return p.RunTargets(args, targetResolver);
}
/// <summary>
/// Executes a generic static parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
public static int Run<T>(string[] args)
{ return new Parser<T>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of a specified type
/// </summary>
/// <typeparam name="T">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t">An instance of the verb class</param>
public static int Run<T>(string[] args, T t)
{ return new Parser<T>().RunTargets(args, t); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2>(string[] args)
{ return new Parser<T1, T2>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
public static int Run<T1, T2>(string[] args, T1 t1, T2 t2)
{ return new Parser<T1, T2>().RunTargets(args, t1, t2); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3>(string[] args)
{ return new Parser<T1, T2, T3>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
public static int Run<T1, T2, T3>(string[] args, T1 t1, T2 t2, T3 t3)
{ return new Parser<T1, T2, T3>().RunTargets(args, t1, t2, t3); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4>(string[] args)
{ return new Parser<T1, T2, T3, T4>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4)
{ return new Parser<T1, T2, T3, T4>().RunTargets(args, t1, t2, t3, t4); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4, T5>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4, T5>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{ return new Parser<T1, T2, T3, T4, T5>().RunTargets(args, t1, t2, t3, t4, t5); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4, T5, T6>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4, T5, T6>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{ return new Parser<T1, T2, T3, T4, T5, T6>().RunTargets(args, t1, t2, t3, t4, t5, t6); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7>().RunTargets(args, t1, t2, t3, t4, t5, t6, t7); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7, T8>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8>().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8); }
/// <summary>
/// Executes a generic static parser of some specified types
/// </summary>
/// <param name="args">The user arguments</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().RunStatic(args); }
/// <summary>
/// Executes a generic parser of some specified types
/// </summary>
/// <typeparam name="T1">The type of the parser</typeparam>
/// <typeparam name="T2">The type of the parser</typeparam>
/// <typeparam name="T3">The type of the parser</typeparam>
/// <typeparam name="T4">The type of the parser</typeparam>
/// <typeparam name="T5">The type of the parser</typeparam>
/// <typeparam name="T6">The type of the parser</typeparam>
/// <typeparam name="T7">The type of the parser</typeparam>
/// <typeparam name="T8">The type of the parser</typeparam>
/// <typeparam name="T9">The type of the parser</typeparam>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
/// <param name="t9">An instance of the verb class</param>
public static int Run<T1, T2, T3, T4, T5, T6, T7, T8, T9>(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{ return new Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9>().RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8, t9); }
}
/// <summary>
/// A command-line arguments parser of the specified type
/// </summary>
/// <typeparam name="T"></typeparam>
public class Parser<T> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t">An instance of the verb class</param>
public void Run(string[] args, T t)
{
base.RunTargets(args, t);
}
}
public class Parser<T1, T2> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2)
{
base.RunTargets(args, t1, t2);
}
}
public class Parser<T1, T2, T3> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3)
{
base.RunTargets(args, t1, t2, t3);
}
}
public class Parser<T1, T2, T3, T4> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4)
{
base.RunTargets(args, t1, t2, t3, t4);
}
}
public class Parser<T1, T2, T3, T4, T5> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{
base.RunTargets(args, t1, t2, t3, t4, t5);
}
}
public class Parser<T1, T2, T3, T4, T5, T6> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{
base.RunTargets(args, t1, t2, t3, t4, t5, t6);
}
}
public class Parser<T1, T2, T3, T4, T5, T6, T7> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{
base.RunTargets(args, t1, t2, t3, t4, t5, t6, t7);
}
}
public class Parser<T1, T2, T3, T4, T5, T6, T7, T8> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{
base.RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8);
}
}
public class Parser<T1, T2, T3, T4, T5, T6, T7, T8, T9> : MultiParser
{
/// <summary>
/// Executes the parser based on the specified targets
/// </summary>
/// <param name="args">The user arguments</param>
/// <param name="t1">An instance of the verb class</param>
/// <param name="t2">An instance of the verb class</param>
/// <param name="t3">An instance of the verb class</param>
/// <param name="t4">An instance of the verb class</param>
/// <param name="t5">An instance of the verb class</param>
/// <param name="t6">An instance of the verb class</param>
/// <param name="t7">An instance of the verb class</param>
/// <param name="t8">An instance of the verb class</param>
/// <param name="t9">An instance of the verb class</param>
public void Run(string[] args, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{
base.RunTargets(args, t1, t2, t3, t4, t5, t6, t7, t8, t9);
}
}
}
================================================
FILE: CLAP/ParserRegistration.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using CLAP.Interception;
using System.Reflection;
namespace CLAP
{
/// <summary>
/// Provides registration features for parser instances
/// </summary>
public sealed class ParserRegistration
{
#region Fields
private readonly Type[] m_types;
private IDictionary<string, Type> m_registeredParsersByAlias;
#endregion Fields
#region Properties
internal Dictionary<string, GlobalParameterHandler> RegisteredGlobalHandlers { get; private set; }
internal Dictionary<string, Action<string>> RegisteredHelpHandlers { get; private set; }
internal Action RegisteredEmptyHandler { get; private set; }
internal Action<ExceptionContext> RegisteredErrorHandler { get; private set; }
internal Action<PreVerbExecutionContext> RegisteredPreVerbInterceptor { get; private set; }
internal Action<PostVerbExecutionContext> RegisteredPostVerbInterceptor { get; private set; }
internal Func<string> HelpGetter { get; private set; }
internal Func<ParameterInfo, Type, string, string, object> ParameterValueGetter { get; private set; }
#endregion Properties
#region Constructors
public ParserRegistration(
Type[] types,
Func<string> helpGetter)
{
m_types = types;
RegisterParserTypeAliases();
RegisteredGlobalHandlers = new Dictionary<string, GlobalParameterHandler>();
RegisteredHelpHandlers = new Dictionary<string, Action<string>>();
HelpGetter = helpGetter;
ParameterValueGetter = ValuesFactory.GetValueForParameter;
}
#endregion Constructors
#region Public Methods
/// <summary>
/// Registers a help handler that is executed when the user requests for help
/// </summary>
/// <param name="names">The names (CSV) to be registered as help parameters. For example: "?,h,help"</param>
/// <param name="helpHandler">The action to be executed</param>
public void HelpHandler(string names, Action<string> helpHandler)
{
if (helpHandler == null)
{
throw new ArgumentNullException("helpHandler");
}
RegisterHelpHandlerInternal(names, helpHandler);
}
/// <summary>
/// Registers an empty help handler that is executed when there is no input
/// </summary>
/// <param name="handler">The action to be executed</param>
public void EmptyHelpHandler(Action<string> handler)
{
if (handler == null)
{
throw new ArgumentNullException("handler");
}
EmptyHandler(delegate
{
var help = HelpGetter();
handler(help);
});
}
/// <summary>
/// Registers an empty handler that is executed when there is no input
/// </summary>
/// <param name="handler">The action to be executed</param>
public void EmptyHandler(Action handler)
{
if (handler == null)
{
throw new ArgumentNullException("handler");
}
if (RegisteredEmptyHandler != null)
{
throw new MoreThanOneEmptyHandlerException();
}
RegisteredEmptyHandler = handler;
}
/// <summary>
/// Registers an error handler that is executed when an exception is thrown
/// </summary>
/// <param name="handler">The action to be executed</param>
public void ErrorHandler(Action<ExceptionContext> handler)
{
if (handler == null)
{
throw new ArgumentNullException("handler");
}
if (RegisteredErrorHandler != null)
{
throw new MoreThanOneErrorHandlerException();
}
RegisteredErrorHandler = handler;
}
/// <summary>
/// Registers a pre-verb execution interceptor
/// </summary>
/// <param name="interceptor">The action to be executed before each verb is executed</param>
public void PreVerbInterceptor(Action<PreVerbExecutionContext> interceptor)
{
if (interceptor == null)
{
throw new ArgumentNullException("interceptor");
}
if (RegisteredPreVerbInterceptor != null)
{
throw new MoreThanOnePreVerbInterceptorException();
}
RegisteredPreVerbInterceptor = interceptor;
}
/// <summary>
/// Registers a post-verb execution interceptor
/// </summary>
/// <param name="interceptor">The action to be executed after each verb is executed</param>
public void PostVerbInterceptor(Action<PostVerbExecutionContext> interceptor)
{
if (interceptor == null)
{
throw new ArgumentNullException("interceptor");
}
if (RegisteredPostVerbInterceptor != null)
{
throw new MoreThanOnePostVerbInterceptorException();
}
RegisteredPostVerbInterceptor = interceptor;
}
/// <summary>
/// Registers a global parameter handler
/// </summary>
/// <param name="names">The names (CSV) to be registered as boolean parameters (switches)</param>
/// <param name="action">The action to execute</param>
public void ParameterHandler(string names, Action action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
ParameterHandler(
names,
new Action<bool>(delegate { action(); }),
new ParameterOptions());
}
/// <summary>
/// Registers a global parameter handler
/// </summary>
/// <param name="names">The names (CSV) to be registered as boolean parameters (switches)</param>
/// <param name="action">The action to execute</param>
/// <param name="description">The parameter description (for help generation)</param>
public void ParameterHandler(string names, Action action, string description)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
ParameterHandler(
names,
new Action<bool>(delegate { action(); }),
new ParameterOptions
{
Description = description,
});
}
/// <summary>
/// Registers a global parameter handler
/// </summary>
/// <typeparam name="TParameter">The type of the parameter</typeparam>
/// <param name="names">The names (CSV) to be registered as parameters</param>
/// <param name="action">The action to execute</param>
public void ParameterHandler<TParameter>(string names, Action<TParameter> action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
ParameterHandler(
names,
action,
new ParameterOptions());
}
/// <summary>
/// Registers a global parameter handler
/// </summary>
/// <typeparam name="TParameter">The type of the parameter</typeparam>
/// <param name="names">The names (CSV) to be registered as parameters</param>
/// <param name="action">The action to execute</param>
/// <param name="description">The parameter description (for help generation)</param>
[Obsolete("Use ParameterOptions")]
public void ParameterHandler<TParameter>(string names, Action<TParameter> action, string description)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
RegisterParameterHandlerInternal(
names,
action,
new ParameterOptions
{
Description = description,
});
}
public void ParameterHandler<TParameter>(string names, Action<TParameter> action, ParameterOptions options)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
RegisterParameterHandlerInternal(
names,
action,
options);
}
/// <summary>
/// Attempts to get a registered type by the provided value. The value will first be checked against all of the
/// registered type names, and then if no match is found, by the 'TargetAlias' values applied to the types (if any).
/// </summary>
/// <param name="typeNameOrAlias">The name of the requested type or 'null'</param>
/// <returns>The matching type, or 'null' if no match is found.</returns>
public Type GetTargetType(string typeNameOrAlias)
{
var matchByTypeName = m_types.FirstOrDefault(t => t.Name.Equals(typeNameOrAlias, StringComparison.OrdinalIgnoreCase));
if (matchByTypeName != null)
return matchByTypeName;
return m_registeredParsersByAlias.ContainsKey(typeNameOrAlias)
? m_registeredParsersByAlias[typeNameOrAlias]
: null;
}
#endregion Public Methods
#region Private Methods
private void RegisterParserTypeAliases()
{
foreach (var type in m_types)
{
var parserTypeTargetAlias = GetTargetAliasAttributeValue(type);
if (string.IsNullOrEmpty(parserTypeTargetAlias))
continue;
if (m_registeredParsersByAlias == null)
m_registeredParsersByAlias = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
if (m_registeredParsersByAlias.ContainsKey(parserTypeTargetAlias))
throw new DuplicateTargetAliasException(parserTypeTargetAlias);
m_registeredParsersByAlias.Add(parserTypeTargetAlias, type);
}
}
private string GetTargetAliasAttributeValue(Type targetType)
{
var aliasAttribute = targetType.GetCustomAttributes(typeof(TargetAliasAttribute), false).FirstOrDefault() as TargetAliasAttribute;
return (aliasAttribute != null) ? aliasAttribute.Alias : string.Empty;
}
private void RegisterParameterHandlerInternal<TParameter>(string names, Action<TParameter> action, ParameterOptions options)
{
var objectAction = new Action<string>(str =>
{
object v = null;
if (typeof(TParameter) == typeof(bool) && str == null)
{
v = true;
}
else
{
v = ParameterValueGetter(null, typeof(TParameter), string.Empty, str);
}
action((TParameter)v);
});
RegisteredGlobalHandlers.Add(
names,
new GlobalParameterHandler
{
Names = names.CommaSplit(),
Handler = objectAction,
Description = options.Description,
Separator = options.Separator,
Type = typeof(TParameter),
});
}
private void RegisterHelpHandlerInternal(string names, Action<string> helpHandler)
{
RegisterHelpHandlerInternal(
names.CommaSplit(),
helpHandler);
}
private void RegisterHelpHandlerInternal(IEnumerable<string> names, Action<string> helpHandler)
{
foreach (var name in names)
{
var key = name.ToLowerInvariant();
if (RegisteredHelpHandlers.ContainsKey(key))
{
throw new InvalidOperationException("'{0}' is already registered as a help handler".FormatWith(key));
}
RegisteredHelpHandlers.Add(key, helpHandler);
}
}
#endregion Private Methods
}
public sealed class ParameterOptions
{
/// <summary>
/// The parameter description
/// </summary>
public string Description { get; set; }
/// <summary>
/// In case of an array type - the values separator.
/// Unless specified, the default is a comma (",")
/// </summary>
public string Separator { get; set; }
}
internal class GlobalParameterHandler
{
internal IEnumerable<string> Names { get; set; }
internal Action<string> Handler { get; set; }
internal string Description { get; set; }
internal string Separator { get; set; }
internal Type Type { get; set; }
}
}
================================================
FILE: CLAP/ParserRunner.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;
using CLAP.Interception;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
internal class ParserRunner
{
#region Fields
// The possible prefixes of a parameter
//
internal readonly static string[] ArgumentPrefixes = new[] { "/", "-" };
private readonly static string s_fileInputSuffix = "@";
private readonly ParserRegistration m_registration;
private readonly HelpGeneratorBase m_helpGenerator;
#endregion Fields
#region Properties
internal Type Type { get; private set; }
internal ParserRegistration Register
{
get { return m_registration; }
}
#endregion Properties
#region Constructors
internal ParserRunner(Type type, ParserRegistration parserRegistration, HelpGeneratorBase helpGenerator)
{
Debug.Assert(type != null);
Type = type;
m_registration = parserRegistration;
Validate(type, m_registration);
m_helpGenerator = helpGenerator;
}
#endregion Constructors
#region Public Methods
public int Run(string[] args, object obj)
{
return TryRunInternal(args, obj);
}
#endregion Public Methods
#region Private Methods
private int TryRunInternal(string[] args, object obj)
{
try
{
return RunInternal(args, obj);
}
catch (Exception ex)
{
var rethrow = HandleError(ex, obj);
if (rethrow)
{
throw;
}
return MultiParser.ErrorCode;
}
}
private int RunInternal(string[] args, object obj)
{
//
// *** empty args are handled by the multi-parser
//
//
Debug.Assert(args.Length > 0 && args.All(a => !string.IsNullOrEmpty(a)));
// the first arg should be the verb, unless there is no verb and a default is used
//
var firstArg = args[0];
if (HandleHelp(firstArg, obj))
{
return MultiParser.ErrorCode;
}
var verb = firstArg;
// a flag, in case there is no verb
//
var noVerb = false;
// find the method by the given verb
//
var typeVerbs = GetVerbs()
.ToDictionary(v => v, v => GetParameters(v.MethodInfo).ToList());
// arguments
var notVerbs = args
.Where(a => a.StartsWith(ArgumentPrefixes))
.ToList();
var globals = GetDefinedGlobals()
.Where(g => notVerbs.Any(a => a.Substring(1).StartsWith(g.Name.ToLowerInvariant())))
.ToList();
var notVerbsNotGlobals = notVerbs
.Where(a => globals.All(g => !a.Substring(1).StartsWith(g.Name.ToLowerInvariant())))
.ToList();
// find the method by name, parameter count and parameter names
var methods = (
from v in typeVerbs
where v.Key.Names.Contains(verb.ToLowerInvariant())
where v.Value.Count == notVerbs.Count
select v
).ToList();
Method method = SelectMethod(methods, notVerbs);
// if arguments do not match parameter names, exclude globals
methods = (
from v in typeVerbs
where v.Key.Names.Contains(verb.ToLowerInvariant())
where v.Value.Count == notVerbsNotGlobals.Count
select v
).ToList();
if (method == null)
{
method = SelectMethod(methods, notVerbsNotGlobals);
}
// if arguments do not match parameters names, exclude optional parameters
if (method == null)
{
const bool avoidOptionalParameters = false;
method = SelectMethod(methods, notVerbsNotGlobals, avoidOptionalParameters);
}
// if arguments do not match parameter names, use only argument count (without globals)
if (method == null)
{
method = methods.FirstOrDefault().Key;
}
// if nothing matches...
if (method == null)
{
method = typeVerbs.FirstOrDefault(v => v.Key.Names.Contains(verb.ToLowerInvariant())).Key;
}
// if no method is found - a default must exist
if (method == null)
{
// if there is a verb input but no method was found
// AND
// the first arg is not an input argument (doesn't start with "-" etc)
//
if (verb != null && !verb.StartsWith(ArgumentPrefixes))
{
throw new VerbNotFoundException(verb);
}
method = typeVerbs.FirstOrDefault(v => v.Key.IsDefault).Key;
// no default - error
//
if (method == null)
{
throw new MissingDefaultVerbException();
}
noVerb = true;
}
// if there is a verb - skip the first arg
//
var inputArgs = MapArguments(noVerb ? args : args.Skip(1));
HandleGlobals(inputArgs, obj);
// a list of the available parameters
//
var paremetersList = GetParameters(method.MethodInfo);
// a list of values, used when invoking the method
//
var parameterValues = ValuesFactory.CreateParameterValues(method, obj, inputArgs, paremetersList);
ValidateVerbInput(method, parameterValues.Select(kvp => kvp.Value).ToList());
// if some args weren't handled
//
if (inputArgs.Any())
{
throw new UnhandledParametersException(inputArgs);
}
return Execute(obj, method, parameterValues);
}
private static Method SelectMethod(List<KeyValuePair<Method, List<Parameter>>> methods, List<string> args, bool allowOptionalParameters = true)
{
Method method = null;
foreach (var m in methods)
{
bool methodFound = false;
var parameters = m.Value;
if (!allowOptionalParameters)
{
parameters = m.Value
.Where(p => p.Default != null)
.ToList();
}
foreach (var p in parameters)
{
bool parameterMatches = false;
foreach (var name in p.Names)
{
if (args.Any(a => a.Substring(1).Equals(name)))
{
parameterMatches = true;
break;
}
}
if (!parameterMatches)
{
break;
}
methodFound = true;
}
if (methodFound)
{
method = m.Key;
break;
}
}
return method;
}
private int Execute(
object target,
Method method,
ParameterAndValue[] parameters)
{
// pre-interception
//
var preVerbExecutionContext = PreInterception(target, method, parameters);
Exception verbException = null;
try
{
// actual verb execution
//
if (!preVerbExecutionContext.Cancel)
{
// invoke the method with the list of parameters
//
MethodInvoker.Invoke(method.MethodInfo, target, parameters.Select(p => p.Value).ToArray());
}
}
catch (TargetInvocationException tex)
{
PreserveStackTrace(tex.InnerException);
verbException = tex.InnerException;
}
catch (Exception ex)
{
verbException = ex;
}
finally
{
try
{
PostInterception(target, method, parameters, preVerbExecutionContext, verbException);
}
finally
{
if (verbException != null)
{
var rethrow = HandleError(verbException, target);
if (rethrow)
{
throw verbException;
}
}
}
}
return verbException == null ? MultiParser.SuccessCode : MultiParser.ErrorCode;
}
static void PreserveStackTrace(Exception e)
{
var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
var mgr = new ObjectManager(null, ctx);
var si = new SerializationInfo(e.GetType(), new FormatterConverter());
e.GetObjectData(si, ctx);
mgr.RegisterObject(e, 1, si); // prepare for SetObjectData
mgr.DoFixups(); // ObjectManager calls SetObjectData
// voila, e is unmodified save for _remoteStackTraceString
}
private void PostInterception(
object target,
Method method,
ParameterAndValue[] parameters,
PreVerbExecutionContext preVerbExecutionContext,
Exception verbException)
{
var postVerbExecutionContext = new PostVerbExecutionContext(
method,
target,
parameters,
preVerbExecutionContext.Cancel,
verbException,
preVerbExecutionContext.UserContext);
// registered interceptors get top priority
//
if (m_registration.RegisteredPostVerbInterceptor != null)
{
m_registration.RegisteredPostVerbInterceptor(postVerbExecutionContext);
}
else
{
var postInterceptionMethods = Type.GetMethodsWith<PostVerbExecutionAttribute>();
// try a defined interceptor type
//
if (postInterceptionMethods.Any())
{
Debug.Assert(postInterceptionMethods.Count() == 1);
var postInterceptionMethod = postInterceptionMethods.First();
MethodInvoker.Invoke(postInterceptionMethod, target, new[] { postVerbExecutionContext });
}
else
{
// try a defined interceptor type
//
if (Type.HasAttribute<VerbInterception>())
{
var interception = Type.GetAttribute<VerbInterception>();
var interceptor = (IPostVerbInterceptor)Activator.CreateInstance(interception.InterceptorType);
interceptor.AfterVerbExecution(postVerbExecutionContext);
}
}
}
}
private PreVerbExecutionContext PreInterception(
object target,
Method method,
ParameterAndValue[] parameters)
{
var preVerbExecutionContext = new PreVerbExecutionContext(method, target, parameters);
// registered interceptors get top priority
//
if (m_registration.RegisteredPreVerbInterceptor != null)
{
m_registration.RegisteredPreVerbInterceptor(preVerbExecutionContext);
}
else
{
// try a defined verb interceptor
//
var preInterceptionMethods = Type.GetMethodsWith<PreVerbExecutionAttribute>();
if (preInterceptionMethods.Any())
{
Debug.Assert(preInterceptionMethods.Count() == 1);
var preInterceptionMethod = preInterceptionMethods.First();
MethodInvoker.Invoke(preInterceptionMethod, target, new[] { preVerbExecutionContext });
}
else
{
// try a defined interceptor type
//
if (Type.HasAttribute<VerbInterception>())
{
var interception = Type.GetAttribute<VerbInterception>();
var interceptor = (IPreVerbInterceptor)Activator.CreateInstance(interception.InterceptorType);
interceptor.BeforeVerbExecution(preVerbExecutionContext);
}
}
}
return preVerbExecutionContext;
}
private static void ValidateVerbInput(Method method, List<object> parameterValues)
{
var methodParameters = method.MethodInfo.GetParameters();
// validate all parameters
//
var validators = method.MethodInfo.GetInterfaceAttributes<ICollectionValidation>().Select(a => a.GetValidator());
if (validators.Any())
{
var parametersAndValues = new List<ValueInfo>();
methodParameters.Each((p, i) =>
{
parametersAndValues.Add(new ValueInfo(p.Name, p.ParameterType, parameterValues[i]));
});
// all validators must pass
//
foreach (var validator in validators)
{
validator.Validate(parametersAndValues.ToArray());
}
}
}
internal static void Validate(Type type, ParserRegistration registration)
{
// no more than one default verb
//
var verbMethods = type.GetMethodsWith<VerbAttribute>().
Select(m => new Method(m));
var defaultVerbs = verbMethods.Where(m => m.IsDefault);
if (defaultVerbs.Count() > 1)
{
throw new MoreThanOneDefaultVerbException(defaultVerbs.Select(m => m.MethodInfo.Name));
}
// no more than one error handler
//
ValidateDefinedErrorHandlers(type);
// validate empty handlers (and empty help handlers)
//
ValidateDefinedEmptyHandlers(type);
// validate pre/post interceptors
//
ValidateDefinedPreInterceptors(type);
ValidateDefinedPostInterceptors(type);
// parameters can't have both Default and DefaultProvider
//
ValidateParameterDefaults(verbMethods);
// [Separator] can be applied only to array parameters
//
ValidateSeparators(verbMethods, registration);
// no duplicate globals
//
ValidateDuplicateGlobals(type, registration);
}
private static void ValidateDuplicateGlobals(Type type, ParserRegistration registration)
{
var definedGlobals = type.
GetMethodsWith<GlobalAttribute>().
SelectMany(m =>
{
var att = m.GetAttribute<GlobalAttribute>();
var name = att.Name ?? m.Name;
return att.Aliases.CommaSplit().Union(new[] { name }).Select(s => s.ToLowerInvariant());
}).
ToList();
var globals = registration.RegisteredGlobalHandlers.Keys.Select(k => k.ToLowerInvariant()).ToList();
globals.AddRange(definedGlobals);
var counts = globals.Distinct().ToDictionary(g => g, g => globals.Count(name => name == g));
var duplicate = counts.Where(c => c.Value > 1);
if (duplicate.Any())
{
throw new DuplicateGlobalHandlerException(duplicate.First().Key);
}
}
private static void ValidateParameterDefaults(IEnumerable<Method> verbs)
{
var parameters = verbs.SelectMany(v => v.MethodInfo.GetParameters()).ToList();
// find one with both a Default and a DefaultProvider
//
var hasBothDefaults = parameters.Where(p =>
p.HasAttribute<DefaultValueAttribute>() &&
p.HasAttribute<DefaultProviderAttribute>());
if (hasBothDefaults.Any())
{
throw new AmbiguousParameterDefaultException(hasBothDefaults.First());
}
// make sure all default providers are DefaultProvider
//
var hasInvalidDefaultProvider = parameters.Where(p =>
p.HasAttribute<DefaultProviderAttribute>() &&
!typeof(DefaultProvider).IsAssignableFrom(p.GetAttribute<DefaultProviderAttribute>().DefaultProviderType));
if (hasInvalidDefaultProvider.Any())
{
throw new InvalidParameterDefaultProviderException(hasInvalidDefaultProvider.First());
}
}
private static void ValidateSeparators(IEnumerable<Method> verbs, ParserRegistration registration)
{
// check non-arrays
//
var parameters = verbs.SelectMany(v => v.MethodInfo.GetParameters()).ToList();
var nonArrayWithSeparator = parameters.Where(p => !p.ParameterType.IsArray && p.HasAttribute<SeparatorAttribute>());
if (nonArrayWithSeparator.Any())
{
throw new NonArrayParameterWithSeparatorException(nonArrayWithSeparator.First());
}
// check invalid separators
//
var separators = parameters.
Where(p => p.HasAttribute<SeparatorAttribute>()).
Select(p => Pair.Create(p, p.GetAttribute<SeparatorAttribute>().Separator));
var invalidSeparator = separators.
FirstOrDefault(pair => string.IsNullOrEmpty(pair.Second) || pair.Second.Contains(" "));
if (invalidSeparator != null)
{
throw new InvalidSeparatorException(invalidSeparator.First);
}
var invalidRegisteredHandlers = registration.RegisteredGlobalHandlers.
FirstOrDefault(a =>
a.Value.Type.IsArray &&
(string.IsNullOrEmpty(a.Value.Separator) || a.Value.Separator.Contains(" ")));
}
private static void ValidateDefinedEmptyHandlers(Type type)
{
var definedEmptyHandlers = type.GetMethodsWith<EmptyAttribute>();
var definedEmptyHandlersCount = definedEmptyHandlers.Count();
if (definedEmptyHandlersCount > 0)
{
// empty handler without parameters
//
var definedEmptyHandler = definedEmptyHandlers.First();
var definedEmptyHandlerParameters = definedEmptyHandler.GetParameters();
if (definedEmptyHandlerParameters.Any())
{
if (definedEmptyHandler.HasAttribute<HelpAttribute>())
{
// if empty help handler is not Action<string> - throw
//
if (definedEmptyHandlerParameters.Length > 1 ||
definedEmptyHandlerParameters.First().ParameterType != typeof(string))
{
throw new InvalidHelpHandlerException(definedEmptyHandler);
}
}
else
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [Empty] so it should not have any parameters".FormatWith(definedEmptyHandler));
}
}
if (definedEmptyHandlersCount > 1)
{
// no more than one empty handler
//
throw new MoreThanOneEmptyHandlerException();
}
}
}
private Action<string> GetRegisteredHelpHandler(string input)
{
Debug.Assert(!string.IsNullOrEmpty(input));
Action<string> action = null;
if (m_registration.RegisteredHelpHandlers.TryGetValue(input.ToLowerInvariant(), out action))
{
return action;
}
return null;
}
/// <summary>
/// Creates a map of the input arguments and their string values
/// </summary>
private static Dictionary<string, string> MapArguments(IEnumerable<string> args)
{
var map = new Dictionary<string, string>();
foreach (var arg in args)
{
// all arguments must start with a valid prefix
//
if (!arg.StartsWith(ArgumentPrefixes))
{
throw new MissingArgumentPrefixException(arg, string.Join(",", ArgumentPrefixes));
}
var prefix = arg.Substring(1);
var parts = prefix.Split(new[] { '=', ':' }, 2, StringSplitOptions.RemoveEmptyEntries);
var name = parts[0].ToLowerInvariant();
string valueString = null;
// a switch (a boolean parameter) doesn't need to have a separator,
// in that case, a null string value is mapped
//
if (parts.Length > 1)
{
valueString = parts[1];
// if it has a file input suffix - remove it
//
if (name.EndsWith(s_fileInputSuffix))
{
name = name.Substring(0, name.Length - 1);
// the value is replaced with the content of the input file
//
valueString = FileSystemHelper.ReadAllText(valueString);
}
}
map.Add(name, valueString);
}
return map;
}
/// <summary>
/// Create a list of parameters for the given method
/// </summary>
internal static IEnumerable<Parameter> GetParameters(MethodInfo method)
{
var parameters = method.GetParameters().Select(p => new Parameter(p)).ToList();
// detect duplicates
//
var allNames = parameters.SelectMany(p => p.Names);
var duplicates = allNames.Where(name =>
allNames.Count(n => n.Equals(name, StringComparison.InvariantCultureIgnoreCase)) > 1);
if (duplicates.Any())
{
throw new InvalidOperationException(
"Duplicate parameter names found in {0}: {1}".FormatWith(
method.Name,
duplicates.Distinct().StringJoin(", ")));
}
// try to find short aliases
//
var paramsToFirstCharDict = parameters.ToDictionary(p => p, p => p.ParameterInfo.Name.ToLowerInvariant()[0].ToString());
// if there are no duplicate first-chars
//
if (paramsToFirstCharDict.Values.Distinct().Count() == parameters.Count())
{
foreach (var p in parameters)
{
var c = paramsToFirstCharDict[p];
if (!p.Names.Contains(c))
{
p.Names.Add(c);
}
}
}
return parameters;
}
/// <summary>
/// Create a list of methods (verbs) for the given type
/// </summary>
internal IEnumerable<Method> GetVerbs()
{
var verbMethods = Type.
GetMethodsWith<VerbAttribute>().
Select(m => new Method(m)).
ToList();
if (verbMethods.Select(v => v.MethodInfo.Name[0]).Distinct().Count() == verbMethods.Count())
{
foreach (var v in verbMethods)
{
var c = v.MethodInfo.Name[0].ToString().ToLowerInvariant();
if (!v.Names.Contains(c))
{
v.Names.Add(c);
}
}
}
var defaultVerbs = verbMethods.Where(m => m.IsDefault);
Debug.Assert(defaultVerbs.Count() <= 1);
return verbMethods;
}
/// <summary>
/// Handles any global parameter that has any input
/// </summary>
private void HandleGlobals(Dictionary<string, string> args, object obj)
{
HandleRegisteredGlobals(args);
HandleDefinedGlobals(args, obj);
}
/// <summary>
/// Handles any registered global parameter that has any input
/// </summary>
private void HandleRegisteredGlobals(Dictionary<string, string> args)
{
var handled = new List<string>();
foreach (var kvp in args)
{
var key = m_registration.RegisteredGlobalHandlers.Keys.FirstOrDefault(
k => k.CommaSplit().Contains(kvp.Key));
if (key != null)
{
var handler = m_registration.RegisteredGlobalHandlers[key];
handler.Handler(kvp.Value);
handled.Add(kvp.Key);
}
}
// remove them so later we'll see which ones were not handled
//
foreach (var h in handled)
{
args.Remove(h);
}
}
internal IEnumerable<MethodInfo> GetDefinedGlobals()
{
var globals = Type.GetMethodsWith<GlobalAttribute>();
return globals;
}
internal static IEnumerable<MethodInfo> GetDefinedErrorHandlers(Type type)
{
var errorHandlers = type.GetMethodsWith<ErrorAttribute>();
return errorHandlers;
}
/// <summary>
/// Handles any defined global parameter that has any input
/// </summary>
private void HandleDefinedGlobals(Dictionary<string, string> args, object obj)
{
var globals = GetDefinedGlobals();
foreach (var method in globals)
{
var att = method.GetAttribute<GlobalAttribute>();
var name = att.Name ?? method.Name;
var allNames = new[] { name }.Union(att.Aliases.CommaSplit());
var key = args.Keys.FirstOrDefault(
k => allNames.Any(
n => n.Equals(k, StringComparison.InvariantCultureIgnoreCase)));
if (key != null)
{
var parameters = method.GetParameters();
if (parameters.Length == 0)
{
MethodInvoker.Invoke(method, obj, null);
}
else if (parameters.Length == 1)
{
string stringValue;
if (args.TryGetValue(key, out stringValue))
{
var p = parameters.First();
var value = ValuesFactory.GetValueForParameter(p, p.ParameterType, key, stringValue);
// validation
//
if (value != null && p.HasAttribute<ValidationAttribute>())
{
var parameterValidators = p.GetAttributes<ValidationAttribute>().Select(a => a.GetValidator());
// all validators must pass
//
foreach (var validator in parameterValidators)
{
validator.Validate(new ValueInfo(p.Name, p.ParameterType, value));
}
}
var validators = method.GetInterfaceAttributes<ICollectionValidation>().
Select(a => a.GetValidator());
foreach (var validator in validators)
{
validator.Validate(new[]
{
new ValueInfo(p.Name, p.ParameterType, value),
});
}
MethodInvoker.Invoke(method, obj, new[] { value });
}
}
else
{
throw new NotSupportedException(
"Method {0} has more than one parameter and cannot be handled as a global handler".FormatWith(method.Name));
}
// remove it so later we'll see which ones were not handled
//
args.Remove(key);
}
}
}
private bool HandleHelp(string firstArg, object target)
{
var arg = firstArg;
if (ArgumentPrefixes.Contains(firstArg[0].ToString()))
{
arg = firstArg.Substring(1);
}
Action<string> helpHandler = GetRegisteredHelpHandler(arg);
if (helpHandler != null)
{
helpHandler(m_helpGenerator.GetHelp(this));
return true;
}
var definedHelpMethods = Type.GetMethodsWith<HelpAttribute>();
foreach (var method in definedHelpMethods)
{
var att = method.GetAttribute<HelpAttribute>();
var name = att.Name ?? method.Name;
if (name.Equals(arg, StringComparison.InvariantCultureIgnoreCase) ||
att.Aliases.CommaSplit().Any(s => s.Equals(arg, StringComparison.InvariantCultureIgnoreCase)))
{
try
{
VerifyMethodAndTarget(method, target);
var obj = method.IsStatic ? null : target;
MethodInvoker.Invoke(method, obj, new[] { m_helpGenerator.GetHelp(this) });
return true;
}
catch (TargetParameterCountException ex)
{
throw new InvalidHelpHandlerException(method, ex);
}
catch (ArgumentException ex)
{
throw new InvalidHelpHandlerException(method, ex);
}
}
}
return false;
}
internal void HandleEmptyArguments(object target)
{
//
// *** registered empty handlers are called by the multi-parser
//
var definedEmptyHandlers = Type.GetMethodsWith<EmptyAttribute>();
var definedEmptyHandlersCount = definedEmptyHandlers.Count();
Debug.Assert(definedEmptyHandlersCount <= 1);
if (definedEmptyHandlersCount == 1)
{
var method = definedEmptyHandlers.First();
VerifyMethodAndTarget(method, target);
var obj = method.IsStatic ? null : target;
// if it is a [Help] handler
//
if (method.HasAttribute<HelpAttribute>())
{
var help = m_helpGenerator.GetHelp(this);
// method should execute because it was already passed validation
//
MethodInvoker.Invoke(method, obj, new[] { help });
}
else
{
MethodInvoker.Invoke(method, obj, null);
}
// don't handle the default verb
//
return;
}
var defaultVerb = GetDefaultVerb();
// if there is a default verb - execute it
//
if (defaultVerb != null)
{
// create an array of arguments that matches the method
//
var parameters = ValuesFactory.CreateParameterValues(
defaultVerb,
target,
new Dictionary<string, string>(),
GetParameters(defaultVerb.MethodInfo));
Execute(target, defaultVerb, parameters);
}
}
private static void VerifyMethodAndTarget(MethodInfo method, object target)
{
if (!method.IsStatic && target == null)
{
throw new ParserExecutionTargetException(
"Method '{0}' is not static but the target object is null".FormatWith(method));
}
if (method.IsStatic && target != null)
{
throw new ParserExecutionTargetException(
"Method '{0}' is static but the target object is not null".FormatWith(method));
}
}
private bool HandleError(Exception ex, object target)
{
var context = new ExceptionContext(ex);
if (m_registration.RegisteredErrorHandler != null)
{
m_registration.RegisteredErrorHandler(context);
return context.ReThrow;
}
else
{
var definedErrorHandlers = GetDefinedErrorHandlers(Type);
Debug.Assert(definedErrorHandlers.Count() <= 1);
var handler = definedErrorHandlers.FirstOrDefault();
if (handler != null)
{
MethodInvoker.Invoke(handler, target, new[] { context });
return context.ReThrow;
}
// no handler - rethrow
//
return true;
}
}
private static void ValidateDefinedErrorHandlers(Type type)
{
// check for too many defined global error handlers
//
var definedErrorHandlers = GetDefinedErrorHandlers(type);
var count = definedErrorHandlers.Count();
// good
//
if (count == 0)
{
return;
}
if (count > 1)
{
throw new MoreThanOneErrorHandlerException();
}
// there is only one defined handler
//
var method = definedErrorHandlers.First();
var parameters = method.GetParameters();
if (parameters.Length > 1)
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [Error] so it should have a single parameter of type CLAP.ExceptionContext".FormatWith(method));
}
else
{
var parameter = parameters.First();
if (parameter.ParameterType != typeof(ExceptionContext))
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [Error] so it should have a single parameter of type CLAP.ExceptionContext".FormatWith(method));
}
}
}
private static void ValidateDefinedPreInterceptors(Type type)
{
// no more that one pre/post interception methods
//
var preInterceptionMethods = type.GetMethodsWith<PreVerbExecutionAttribute>();
var preInterceptionMethodsCount = preInterceptionMethods.Count();
if (preInterceptionMethodsCount == 0)
{
return;
}
else if (preInterceptionMethodsCount > 1)
{
throw new MoreThanOnePreVerbInterceptorException();
}
// there is only one defined interceptor
//
var method = preInterceptionMethods.First();
var parameters = method.GetParameters();
if (parameters.Length > 1)
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [PreVerbExecution] so it should have a single parameter of type CLAP.PreVerbExecutionContext".FormatWith(method));
}
else
{
var parameter = parameters.First();
if (parameter.ParameterType != typeof(PreVerbExecutionContext))
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [PreVerbExecution] so it should have a single parameter of type CLAP.PreVerbExecutionContext".FormatWith(method));
}
}
}
private static void ValidateDefinedPostInterceptors(Type type)
{
// no more that one pre/post interception methods
//
var postInterceptionMethods = type.GetMethodsWith<PostVerbExecutionAttribute>();
var postInterceptionMethodsCount = postInterceptionMethods.Count();
if (postInterceptionMethodsCount == 0)
{
return;
}
else if (postInterceptionMethodsCount > 1)
{
throw new MoreThanOnePostVerbInterceptorException();
}
// there is only one defined interceptor
//
var method = postInterceptionMethods.First();
var parameters = method.GetParameters();
if (parameters.Length > 1)
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [PostVerbExecution] so it should have a single parameter of type CLAP.PostVerbExecutionContext".FormatWith(method));
}
else
{
var parameter = parameters.First();
if (parameter.ParameterType != typeof(PostVerbExecutionContext))
{
throw new ArgumentMismatchException(
"Method '{0}' is marked as [PostVerbExecution] so it should have a single parameter of type CLAP.PostVerbExecutionContext".FormatWith(method));
}
}
}
private Method GetDefaultVerb()
{
var verbs = GetVerbs();
return verbs.FirstOrDefault(v => v.IsDefault);
}
#endregion Private Methods
}
}
================================================
FILE: CLAP/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CLAP")]
[assembly: AssemblyDescription("Command-Line Auto Parser")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("CLAP")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4ad1cbe9-f554-4e42-86ce-4ab9237262ab")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.2")]
[assembly: AssemblyFileVersion("4.2")]
================================================
FILE: CLAP/Publish/CLAP.nuspec
================================================
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>CLAP</id>
<version>${VERSION}</version>
<authors>Adrian Aisemberg, adrianaisemberg@gmail.com</authors>
<owners>Adrian Aisemberg, adrianaisemberg@gmail.com</owners>
<licenseUrl>http://adrianaisemberg.github.com/CLAP/#license</licenseUrl>
<projectUrl>http://adrianaisemberg.github.com/CLAP</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Command-Line Auto Parser</description>
</metadata>
</package>
================================================
FILE: CLAP/Publish/pack.cmd
================================================
@echo off
set PACKPATH=%~dp0_nuget_pack
if exist %PACKPATH% rd /q /s %PACKPATH%
set TEMP_LIB=%PACKPATH%\_lib\net20
set LIB=%PACKPATH%\lib\net20
md %TEMP_LIB%
md %LIB%
copy %~dp0..\bin\Release20\CLAP.??? %TEMP_LIB%
copy %~dp0..\bin\Release20\Newtonsoft.Json.??? %TEMP_LIB%
ilmerge /out:%LIB%\CLAP.dll /internalize %TEMP_LIB%\CLAP.Dll %TEMP_LIB%\Newtonsoft.Json.dll
copy %TEMP_LIB%\CLAP.xml %LIB%
set TEMP_LIB=%PACKPATH%\_lib\net35
set LIB=%PACKPATH%\lib\net35
md %TEMP_LIB%
md %LIB%
copy %~dp0..\bin\Release\CLAP.??? %TEMP_LIB%
copy %~dp0..\bin\Release\Newtonsoft.Json.??? %TEMP_LIB%
ilmerge /out:%LIB%\CLAP.dll /internalize %TEMP_LIB%\CLAP.Dll %TEMP_LIB%\Newtonsoft.Json.dll
copy %TEMP_LIB%\CLAP.xml %LIB%
rd /q /s %PACKPATH%\_lib
copy %~dp0CLAP.nuspec %PACKPATH%
getver %PACKPATH%\lib\net20\CLAP.dll > _ver
set /p VERSION= < _ver
del _ver
fart --quiet %PACKPATH%\CLAP.nuspec ${VERSION} %VERSION%
nuget pack %PACKPATH%\CLAP.nuspec
================================================
FILE: CLAP/Serialization.cs
================================================
using System;
using System.IO;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace CLAP
{
internal static class Serialization
{
public static bool Deserialize(string str, Type type, ref object obj)
{
if (string.IsNullOrEmpty(str))
{
return false;
}
if (str.StartsWith("<"))
{
obj = DeserializeXml(str, type);
return true;
}
else if (str.StartsWith(new[] { "{", "[" }))
{
obj = DeserializeJson(str, type);
return true;
}
return false;
}
private static object DeserializeJson(string json, Type type)
{
return JsonConvert.DeserializeObject(json, type);
}
public static object DeserializeXml(string xml, Type type)
{
var serializer = new XmlSerializer(type);
using (var reader = new StringReader(xml))
{
var obj = serializer.Deserialize(reader);
return obj;
}
}
}
}
================================================
FILE: CLAP/TargetResolver.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
namespace CLAP
{
public class TargetResolver
{
private readonly Dictionary<Type, Func<object>> targetHash = new Dictionary<Type, Func<object>>();
public TargetResolver()
{
}
public TargetResolver(params object[] targets)
{
foreach (var target in targets)
{
var innerTarget = target;
RegisterTargetType(innerTarget.GetType(), () => innerTarget);
}
}
public void RegisterTargetType<T>(Func<T> resolver)
where T: class
{
RegisterTargetType(typeof (T), () => resolver());
}
private void RegisterTargetType(Type targetType, Func<object> resolver)
{
if (targetHash.ContainsKey(targetType))
throw new ArgumentException("The provided type is already registered.");
targetHash.Add(targetType, resolver);
}
internal Type[] RegisteredTypes { get { return targetHash.Keys.ToArray(); } }
internal object Resolve(Type targetType)
{
if (!targetHash.ContainsKey(targetType))
{
throw new ArgumentException("The requested type is not registered.");
}
return targetHash[targetType]();
}
}
}
================================================
FILE: CLAP/TypeValidator.cs
================================================
using System.Collections;
using System.Diagnostics;
using System.Reflection;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
internal static class TypeValidator
{
public static void Validate(object obj)
{
if (Ignore(obj))
{
return;
}
Debug.Assert(obj != null);
var type = obj.GetType();
// type's validators:
// first use all the validators defined over this type
//
var validators = type.
GetAttributes<CollectionValidationAttribute>().
Select(a => a.GetValidator());
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var propsAndValues = properties.
Where(p => p.GetIndexParameters().None()).
Select(p => new ValueInfo(p.Name, p.PropertyType, p.GetValue(obj, null))).
ToArray();
foreach (var validator in validators)
{
validator.Validate(propsAndValues);
}
// no need to validate properties of GAC objects
//
if (!type.Assembly.GlobalAssemblyCache &&
!type.IsArray)
{
// property validators:
// validate each property value, in case property is a custom class
//
foreach (var property in properties)
{
var value = property.GetValue(obj, null);
// single validators
//
var propertySingleValidators = property.
GetAttributes<ValidationAttribute>().
Select(a => a.GetValidator());
foreach (var propertySingleValidator in propertySingleValidators)
{
propertySingleValidator.Validate(new ValueInfo(property.Name, property.PropertyType, value));
}
// no need to validate primitives etc with collection validators
//
if (!Ignore(value))
{
// collection validators
//
var propertyCollectionValidators = property.
GetAttributes<CollectionValidationAttribute>().
Select(a => a.GetValidator());
foreach (var propertyValidator in propertyCollectionValidators)
{
var propertyPropsAndValues = value.GetType().
GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).
Where(p => p.GetIndexParameters().None()).
Select(p => new ValueInfo(p.Name, p.PropertyType, p.GetValue(value, null))).
ToArray();
propertyValidator.Validate(propertyPropsAndValues);
}
}
}
// recursion:
// validate all values, in case their type has additional validation
//
foreach (var value in propsAndValues.Select(p => p.Value))
{
Validate(value);
}
}
// IEnumerable
//
var collection = obj as IEnumerable;
if (collection != null)
{
foreach (var item in collection)
{
Validate(item);
}
}
}
private static bool Ignore(object obj)
{
if (obj == null ||
obj is string)
{
return true;
}
if (obj is IEnumerable)
{
return false;
}
var type = obj.GetType();
if (type.IsArray ||
type.IsEnum ||
type.Assembly.GlobalAssemblyCache)
{
return true;
}
return false;
}
}
}
================================================
FILE: CLAP/Utils.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
#if !FW2
using System.Linq;
#endif
namespace CLAP
{
internal static class Utils
{
public static string FormatWith(this string format, params object[] args)
{
return string.Format(format, args);
}
public static T GetAttribute<T>(this MethodInfo method) where T : Attribute
{
var att = Attribute.GetCustomAttribute(method, typeof(T));
return (T)att;
}
public static T GetAttribute<T>(this Type type) where T : Attribute
{
var att = Attribute.GetCustomAttribute(type, typeof(T));
return (T)att;
}
public static T GetAttribute<T>(this ParameterInfo parameter) where T : Attribute
{
var att = Attribute.GetCustomAttribute(parameter, typeof(T));
return (T)att;
}
public static IEnumerable<T> GetAttributes<T>(this ParameterInfo parameter) where T : Attribute
{
var atts = Attribute.
gitextract_kfd419ot/
├── .gitignore
├── CLAP/
│ ├── CLAP.csproj
│ ├── CollectionValidationAttribute.cs
│ ├── CoverageExcludeAttribute.cs
│ ├── DefaultHelpGenerator.cs
│ ├── DefaultProvider.cs
│ ├── EmptyAttribute.cs
│ ├── EnvironmentParserHandlers.cs
│ ├── ErrorAttribute.cs
│ ├── ExceptionContext.cs
│ ├── Exceptions.cs
│ ├── FW2Stuff.cs
│ ├── FileSystemHelper.cs
│ ├── GlobalAttribute.cs
│ ├── HelpAttribute.cs
│ ├── HelpGeneratorBase.cs
│ ├── HelpInfo.cs
│ ├── IValidation.cs
│ ├── Interception/
│ │ ├── IVerbInterceptor.cs
│ │ ├── ParameterAndValue.cs
│ │ ├── PostVerbExecutionAttribute.cs
│ │ ├── PostVerbExecutionContext.cs
│ │ ├── PreVerbExecutionAttribute.cs
│ │ ├── PreVerbExecutionContext.cs
│ │ ├── UserVerbExecutionContext.cs
│ │ └── VerbInterception.cs
│ ├── Method.cs
│ ├── MethodInvoker.cs
│ ├── MultiParser.cs
│ ├── Pair.cs
│ ├── Parameter.cs
│ ├── ParameterAttribute.cs
│ ├── ParametersExpressionValidator.cs
│ ├── Parser.Console.cs
│ ├── Parser.WinForms.cs
│ ├── Parser.cs
│ ├── ParserRegistration.cs
│ ├── ParserRunner.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Publish/
│ │ ├── CLAP.nuspec
│ │ └── pack.cmd
│ ├── Serialization.cs
│ ├── TargetResolver.cs
│ ├── TypeValidator.cs
│ ├── Utils.cs
│ ├── Validation/
│ │ ├── DirectoryExistsAttribute.cs
│ │ ├── FileExistsAttribute.cs
│ │ ├── Less.cs
│ │ ├── LessOrEqual.cs
│ │ ├── More.cs
│ │ ├── MoreOrEqual.cs
│ │ ├── NumberValidator.cs
│ │ ├── PathExistsAttribute.cs
│ │ ├── Regex.cs
│ │ └── ValidateAttribute.cs
│ ├── ValidationAttribute.cs
│ ├── ValueInfo.cs
│ ├── ValuesFactory.cs
│ ├── VerbAttribute.cs
│ ├── VerbExecutionContext.cs
│ └── packages.config
├── CLAP.sln
├── ConsoleTest/
│ ├── ConsoleTest.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── app.config
├── README.md
├── Tests/
│ ├── MultiParserTests.cs
│ ├── ParserRegistrationTests.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Samples.cs
│ ├── StaticSamples.cs
│ ├── Tests.cs
│ ├── Tests.csproj
│ ├── UtilsTests.cs
│ └── packages.config
├── WinFormTest/
│ ├── Form1.Designer.cs
│ ├── Form1.cs
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ └── Settings.settings
│ └── WinFormTest.csproj
├── license.txt
└── packages/
├── Moq.4.0.10827/
│ ├── License.txt
│ ├── Moq.chm
│ └── lib/
│ ├── NET35/
│ │ ├── Moq.pdb
│ │ └── Moq.xml
│ ├── NET40/
│ │ ├── Moq.pdb
│ │ └── Moq.xml
│ └── Silverlight4/
│ ├── Moq.Silverlight.pdb
│ └── Moq.Silverlight.xml
├── NUnit.2.5.10.11092/
│ ├── NUnitFitTests.html
│ ├── fit-license.txt
│ ├── lib/
│ │ └── nunit.framework.xml
│ ├── license.txt
│ └── tools/
│ ├── NUnitTests.VisualState.xml
│ ├── NUnitTests.config
│ ├── NUnitTests.nunit
│ ├── TestResult.xml
│ ├── agent.conf
│ ├── agent.log.conf
│ ├── launcher.log.conf
│ ├── nunit-agent-x86.exe.config
│ ├── nunit-agent.exe.config
│ ├── nunit-console-x86.exe.config
│ ├── nunit-console.exe.config
│ ├── nunit-x86.exe.config
│ ├── nunit.exe.config
│ ├── pnunit-agent.exe.config
│ ├── pnunit-launcher.exe.config
│ ├── runFile.exe.config
│ ├── runpnunit.bat
│ └── test.conf
├── Newtonsoft.Json.4.0.8/
│ └── lib/
│ ├── net20/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── net35/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── net40/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── sl3-wp/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ ├── sl4/
│ │ ├── Newtonsoft.Json.pdb
│ │ └── Newtonsoft.Json.xml
│ └── sl4-windowsphone71/
│ ├── Newtonsoft.Json.pdb
│ └── Newtonsoft.Json.xml
└── repositories.config
Condensed preview — 119 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,166K chars).
[
{
"path": ".gitignore",
"chars": 113,
"preview": "*.docstates\n*.suo\n*.user\nbin\nobj\nUpgradeLog.XML\n_UpgradeReport_Files/\n*.nupkg\n/_ReSharper.*/\n/Metrics.typemock.*\n"
},
{
"path": "CLAP/CLAP.csproj",
"chars": 7365,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso..."
},
{
"path": "CLAP/CollectionValidationAttribute.cs",
"chars": 514,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Validates a collection of parameters of properties\n /// </..."
},
{
"path": "CLAP/CoverageExcludeAttribute.cs",
"chars": 63,
"preview": "internal class CoverageExcludeAttribute : System.Attribute { }"
},
{
"path": "CLAP/DefaultHelpGenerator.cs",
"chars": 6208,
"preview": "using System;\nusing System.Text;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace CLAP\n{\n internal class DefaultHelpGe..."
},
{
"path": "CLAP/DefaultProvider.cs",
"chars": 293,
"preview": "\nnamespace CLAP\n{\n public abstract class DefaultProvider\n {\n public abstract object GetDefault(VerbExecuti..."
},
{
"path": "CLAP/EmptyAttribute.cs",
"chars": 369,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Marks a method to be executed when there is no input.\n ///..."
},
{
"path": "CLAP/EnvironmentParserHandlers.cs",
"chars": 1196,
"preview": "using System;\nusing System.Diagnostics;\nusing System.Windows.Forms;\n\nnamespace CLAP\n{\n internal static class Environ..."
},
{
"path": "CLAP/ErrorAttribute.cs",
"chars": 365,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Marks a method to be executed when an exception occurs.\n /..."
},
{
"path": "CLAP/ExceptionContext.cs",
"chars": 284,
"preview": "using System;\n\nnamespace CLAP\n{\n public sealed class ExceptionContext\n {\n public Exception Exception { get..."
},
{
"path": "CLAP/Exceptions.cs",
"chars": 18925,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace CLAP\n{\n /// <summary>\n /// Ba..."
},
{
"path": "CLAP/FW2Stuff.cs",
"chars": 8365,
"preview": "#if FW2\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace CLAP\n{\n #region Delegat..."
},
{
"path": "CLAP/FileSystemHelper.cs",
"chars": 797,
"preview": "using System.IO;\n\nnamespace CLAP\n{\n /// <summary>\n /// A helper for file reading to allow mocking for tests\n /..."
},
{
"path": "CLAP/GlobalAttribute.cs",
"chars": 1041,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Marks a method as a global parameter.\n /// The method can..."
},
{
"path": "CLAP/HelpAttribute.cs",
"chars": 772,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Marks a method to be called when the user asks for help\n /..."
},
{
"path": "CLAP/HelpGeneratorBase.cs",
"chars": 3876,
"preview": "using System.Collections.Generic;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace CLAP\n{\n public abstract class HelpG..."
},
{
"path": "CLAP/HelpInfo.cs",
"chars": 1329,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace CLAP\n{\n public class HelpInfo\n {\n public List<P..."
},
{
"path": "CLAP/IValidation.cs",
"chars": 714,
"preview": "\nnamespace CLAP\n{\n /// <summary>\n /// Validation of collections of parameters and values\n /// </summary>\n p..."
},
{
"path": "CLAP/Interception/IVerbInterceptor.cs",
"chars": 724,
"preview": "\nnamespace CLAP.Interception\n{\n /// <summary>\n /// Gives interception options to verb execution\n /// </summary..."
},
{
"path": "CLAP/Interception/ParameterAndValue.cs",
"chars": 574,
"preview": "\nnamespace CLAP.Interception\n{\n /// <summary>\n /// A parameter and its value\n /// </summary>\n public sealed..."
},
{
"path": "CLAP/Interception/PostVerbExecutionAttribute.cs",
"chars": 305,
"preview": "using System;\n\nnamespace CLAP.Interception\n{\n /// <summary>\n /// Marks a method to run after each verb is execute..."
},
{
"path": "CLAP/Interception/PostVerbExecutionContext.cs",
"chars": 1340,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace CLAP.Interception\n{\n /// <summary>\n /// The context af..."
},
{
"path": "CLAP/Interception/PreVerbExecutionAttribute.cs",
"chars": 305,
"preview": "using System;\n\nnamespace CLAP.Interception\n{\n /// <summary>\n /// Marks a method to run before each verb is execut..."
},
{
"path": "CLAP/Interception/PreVerbExecutionContext.cs",
"chars": 834,
"preview": "using System.Collections.Generic;\n\nnamespace CLAP.Interception\n{\n /// <summary>\n /// The context before a verb is..."
},
{
"path": "CLAP/Interception/UserVerbExecutionContext.cs",
"chars": 1295,
"preview": "using System.Collections.Generic;\n\nnamespace CLAP.Interception\n{\n public abstract class UserVerbExecutionContext..."
},
{
"path": "CLAP/Interception/VerbInterception.cs",
"chars": 998,
"preview": "using System;\n\nnamespace CLAP.Interception\n{\n /// <summary>\n /// Marks a class to allow verb-interception by a de..."
},
{
"path": "CLAP/Method.cs",
"chars": 1741,
"preview": "using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection;\n\nnamespace CLAP\n{\n /// <summary..."
},
{
"path": "CLAP/MethodInvoker.cs",
"chars": 948,
"preview": "using System.Diagnostics;\nusing System.Reflection;\n\nnamespace CLAP\n{\n /// <summary>\n /// A helper for method invo..."
},
{
"path": "CLAP/MultiParser.cs",
"chars": 7963,
"preview": "using System;\nusing System.Diagnostics;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace CLAP\n{\n /// <summary>\n ///..."
},
{
"path": "CLAP/Pair.cs",
"chars": 527,
"preview": "\nnamespace CLAP\n{\n internal class Pair<TFirst, TSecond>\n {\n public TFirst First { get; private set; }..."
},
{
"path": "CLAP/Parameter.cs",
"chars": 2967,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection;\n\nnamespace CLAP\n{..."
},
{
"path": "CLAP/ParameterAttribute.cs",
"chars": 3928,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// A parameter\n /// </summary>\n [Serializable]\n [Attrib..."
},
{
"path": "CLAP/ParametersExpressionValidator.cs",
"chars": 1888,
"preview": "using System.Data;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace CLAP\n{\n /// <summary>\n /// Validates a collecti..."
},
{
"path": "CLAP/Parser.Console.cs",
"chars": 13261,
"preview": "using System.Diagnostics;\nusing System.Linq;\n\nnamespace CLAP\n{\n public partial class Parser\n {\n /// <summa..."
},
{
"path": "CLAP/Parser.WinForms.cs",
"chars": 13318,
"preview": "using System.Diagnostics;\nusing System.Linq;\n\nnamespace CLAP\n{\n public partial class Parser\n {\n /// <summa..."
},
{
"path": "CLAP/Parser.cs",
"chars": 20034,
"preview": "using System;\nusing System.Diagnostics;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace CLAP\n{\n /// <summary>\n ///..."
},
{
"path": "CLAP/ParserRegistration.cs",
"chars": 13350,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing CLAP.Interception;\nusing System.Reflection;\n\nn..."
},
{
"path": "CLAP/ParserRunner.cs",
"chars": 39749,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection;\nusing System.Runtime..."
},
{
"path": "CLAP/Properties/AssemblyInfo.cs",
"chars": 1275,
"preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled..."
},
{
"path": "CLAP/Publish/CLAP.nuspec",
"chars": 583,
"preview": "<?xml version=\"1.0\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\n <metadata>\n <id>C..."
},
{
"path": "CLAP/Publish/pack.cmd",
"chars": 938,
"preview": "@echo off\nset PACKPATH=%~dp0_nuget_pack\nif exist %PACKPATH% rd /q /s %PACKPATH%\n\nset TEMP_LIB=%PACKPATH%\\_lib\\net20\nset..."
},
{
"path": "CLAP/Serialization.cs",
"chars": 1160,
"preview": "using System;\nusing System.IO;\nusing System.Xml.Serialization;\nusing Newtonsoft.Json;\n\nnamespace CLAP\n{\n internal st..."
},
{
"path": "CLAP/TargetResolver.cs",
"chars": 1405,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace CLAP\n{\n public class TargetResolver..."
},
{
"path": "CLAP/TypeValidator.cs",
"chars": 4321,
"preview": "using System.Collections;\nusing System.Diagnostics;\nusing System.Reflection;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnames..."
},
{
"path": "CLAP/Utils.cs",
"chars": 4963,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\n#if !FW2\nusing System.Linq;\n#endif\n\nnamespace..."
},
{
"path": "CLAP/Validation/DirectoryExistsAttribute.cs",
"chars": 1493,
"preview": "using System;\nusing System.IO;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Directory exists validation:..."
},
{
"path": "CLAP/Validation/FileExistsAttribute.cs",
"chars": 1684,
"preview": "using System;\nusing System.IO;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// File exists validation:\n /// T..."
},
{
"path": "CLAP/Validation/Less.cs",
"chars": 1732,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Less-Than validation:\n /// The numeric value of..."
},
{
"path": "CLAP/Validation/LessOrEqual.cs",
"chars": 1791,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Less-Or-Equal-To validation:\n /// The numeric v..."
},
{
"path": "CLAP/Validation/More.cs",
"chars": 1774,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// More-Than validation:\n /// The numeric value of..."
},
{
"path": "CLAP/Validation/MoreOrEqual.cs",
"chars": 1837,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// More-Or-Equal-To validation:\n /// The numeric v..."
},
{
"path": "CLAP/Validation/NumberValidator.cs",
"chars": 1007,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Number validation\n /// </summary>\n [Serializ..."
},
{
"path": "CLAP/Validation/PathExistsAttribute.cs",
"chars": 1522,
"preview": "using System;\nusing System.IO;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Path exists validation:\n /// T..."
},
{
"path": "CLAP/Validation/Regex.cs",
"chars": 2034,
"preview": "using System;\nusing System.Text.RegularExpressions;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Regex valida..."
},
{
"path": "CLAP/Validation/ValidateAttribute.cs",
"chars": 1915,
"preview": "using System;\n\nnamespace CLAP.Validation\n{\n /// <summary>\n /// Validates all the parameters against an expression..."
},
{
"path": "CLAP/ValidationAttribute.cs",
"chars": 741,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Validation on the parameter's value\n /// </summary>\n [S..."
},
{
"path": "CLAP/ValueInfo.cs",
"chars": 794,
"preview": "using System;\nusing System.Diagnostics;\n\nnamespace CLAP\n{\n /// <summary>\n /// Information about a vluae\n /// <..."
},
{
"path": "CLAP/ValuesFactory.cs",
"chars": 8933,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Reflection;\nusing CLAP.Interc..."
},
{
"path": "CLAP/VerbAttribute.cs",
"chars": 1012,
"preview": "using System;\n\nnamespace CLAP\n{\n /// <summary>\n /// Marks a method as a verb\n /// </summary>\n [Serializable..."
},
{
"path": "CLAP/VerbExecutionContext.cs",
"chars": 910,
"preview": "using System.Collections.Generic;\n\nnamespace CLAP\n{\n /// <summary>\n /// A verb execution context\n /// </summar..."
},
{
"path": "CLAP/packages.config",
"chars": 113,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"Newtonsoft.Json\" version=\"4.0.8\" />\n</packages>"
},
{
"path": "CLAP.sln",
"chars": 6473,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C..."
},
{
"path": "ConsoleTest/ConsoleTest.csproj",
"chars": 4451,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso..."
},
{
"path": "ConsoleTest/Program.cs",
"chars": 19779,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nu..."
},
{
"path": "ConsoleTest/Properties/AssemblyInfo.cs",
"chars": 1378,
"preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled..."
},
{
"path": "ConsoleTest/app.config",
"chars": 141,
"preview": "<?xml version=\"1.0\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0\"/></star..."
},
{
"path": "README.md",
"chars": 3402,
"preview": "CLAP: A Kick-Ass .NET Command-Line Parser\n=========================================\nFull Documentation and Samples\n-----..."
},
{
"path": "Tests/MultiParserTests.cs",
"chars": 22154,
"preview": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing CLAP;\nusing NUnit.Framework;\n\nnamespace Tests\n{\n [Te..."
},
{
"path": "Tests/ParserRegistrationTests.cs",
"chars": 2862,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing CLAP;\nusing NUnit.Framework..."
},
{
"path": "Tests/Properties/AssemblyInfo.cs",
"chars": 1326,
"preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled..."
},
{
"path": "Tests/Samples.cs",
"chars": 30680,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing CLAP;\nusing CLAP.Interception;\nusing CLA..."
},
{
"path": "Tests/StaticSamples.cs",
"chars": 1053,
"preview": "using CLAP;\n\nnamespace Tests\n{\n public class StaticSample_01 { [Verb] public static void Foo() { } [Verb] public voi..."
},
{
"path": "Tests/Tests.cs",
"chars": 69283,
"preview": "using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\nusing System.Reflection;\nusing CLAP;\nusing Moq;\nus..."
},
{
"path": "Tests/Tests.csproj",
"chars": 6561,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso..."
},
{
"path": "Tests/UtilsTests.cs",
"chars": 990,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing CLAP;\nusing NUnit.Framework;\n\nnamespace..."
},
{
"path": "Tests/packages.config",
"chars": 153,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"NUnit\" version=\"2.5.10.11092\" />\n <package id=\"Moq\" v..."
},
{
"path": "WinFormTest/Form1.Designer.cs",
"chars": 1134,
"preview": "namespace WinFormTest\n{\n partial class Form1\n {\n /// <summary>\n /// Required designer variable...."
},
{
"path": "WinFormTest/Form1.cs",
"chars": 340,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nu..."
},
{
"path": "WinFormTest/Program.cs",
"chars": 776,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Forms;\nusing CLAP;\n\nnamespace W..."
},
{
"path": "WinFormTest/Properties/AssemblyInfo.cs",
"chars": 1395,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor..."
},
{
"path": "WinFormTest/Properties/Resources.Designer.cs",
"chars": 2777,
"preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n// This code w..."
},
{
"path": "WinFormTest/Properties/Resources.resx",
"chars": 5494,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n <!-- \n Microsoft ResX Schema \n \n Version 2.0\n \n The prim..."
},
{
"path": "WinFormTest/Properties/Settings.Designer.cs",
"chars": 1064,
"preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n// This code w..."
},
{
"path": "WinFormTest/Properties/Settings.settings",
"chars": 240,
"preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\"..."
},
{
"path": "WinFormTest/WinFormTest.csproj",
"chars": 3673,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso..."
},
{
"path": "license.txt",
"chars": 1104,
"preview": "MIT License\r\n\r\nCopyright (c) 2011 Adrian Aisemberg, SharpRegion\r\n\r\nPermission is hereby granted, free of charge, to any..."
},
{
"path": "packages/Moq.4.0.10827/License.txt",
"chars": 1747,
"preview": "Copyright (c) 2007. Clarius Consulting, Manas Technology Solutions, InSTEDD\nhttp://code.google.com/p/moq/\nAll rights res..."
},
{
"path": "packages/Moq.4.0.10827/lib/NET35/Moq.xml",
"chars": 358735,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Moq</name>\n </assembly>\n <members>\n <member name=\"..."
},
{
"path": "packages/Moq.4.0.10827/lib/NET40/Moq.xml",
"chars": 292076,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Moq</name>\n </assembly>\n <members>\n <member name=\"..."
},
{
"path": "packages/Moq.4.0.10827/lib/Silverlight4/Moq.Silverlight.xml",
"chars": 291028,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Moq.Silverlight</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/NUnit.2.5.10.11092/NUnitFitTests.html",
"chars": 6020,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<html>\n\t<body>\n\t\t<h1>NUnit Acceptance Tests</h1>\n\t\t<p>..."
},
{
"path": "packages/NUnit.2.5.10.11092/fit-license.txt",
"chars": 18347,
"preview": "\r\n\r\n\t\t GNU GENERAL PUBLIC LICENSE\r\n\t\t Version 2, June 1991\r\n\r\n Copyright (C) 1989, 1991 Free Software Foundatio..."
},
{
"path": "packages/NUnit.2.5.10.11092/lib/nunit.framework.xml",
"chars": 545230,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>nunit.framework</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/NUnit.2.5.10.11092/license.txt",
"chars": 1110,
"preview": "Copyright 2002-2008 Charlie Poole\nCopyright 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov\nCopyright..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/NUnitTests.VisualState.xml",
"chars": 11112,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<VisualState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"htt..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/NUnitTests.config",
"chars": 3355,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n<!--\n\t This is the configuration file for the NUnitTests.nunit t..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/NUnitTests.nunit",
"chars": 628,
"preview": "<NUnitProject>\n <Settings appbase=\".\"/>\n <Config name=\"Default\" binpath=\"lib;tests;framework\" runtimeFramework=\"v2.0\">..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/TestResult.xml",
"chars": 798487,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!--This file represents the results of running a test suite-->..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/agent.conf",
"chars": 89,
"preview": "<AgentConfig>\n <Port>8080</Port>\n <PathToAssemblies>.</PathToAssemblies>\n</AgentConfig>"
},
{
"path": "packages/NUnit.2.5.10.11092/tools/agent.log.conf",
"chars": 491,
"preview": "<log4net>\n\t<!-- A1 is set to be a ConsoleAppender -->\n\t<appender name=\"A1\" type=\"log4net.Appender.ConsoleAppender\">\n\n\t\t<..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/launcher.log.conf",
"chars": 491,
"preview": "<log4net>\n\t<!-- A1 is set to be a ConsoleAppender -->\n\t<appender name=\"A1\" type=\"log4net.Appender.ConsoleAppender\">\n\n\t\t<..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit-agent-x86.exe.config",
"chars": 2536,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n \n <runtime>\n <!-- We need this so test exceptions don't cra..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit-agent.exe.config",
"chars": 2536,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n \n <runtime>\n <!-- We need this so test exceptions don't cra..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit-console-x86.exe.config",
"chars": 2530,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n\n <runtime>\n <!-- We need this so test exceptions don't crash..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit-console.exe.config",
"chars": 2530,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n\n <runtime>\n <!-- We need this so test exceptions don't crash..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit-x86.exe.config",
"chars": 2991,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n <!--\n Application settings for NUnit-gui.exe. Do NOT put se..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/nunit.exe.config",
"chars": 2991,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n <!--\n Application settings for NUnit-gui.exe. Do NOT put se..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/pnunit-agent.exe.config",
"chars": 2768,
"preview": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<configuration>\n\n <!-- Set the level for tracing NUnit itself -->\n <!--..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/pnunit-launcher.exe.config",
"chars": 2768,
"preview": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n<configuration>\n\n <!-- Set the level for tracing NUnit itself -->\n <!--..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/runFile.exe.config",
"chars": 1751,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n <startup>\n\t <supportedRuntime version=\"v2.0.50727\" />\n\t <sup..."
},
{
"path": "packages/NUnit.2.5.10.11092/tools/runpnunit.bat",
"chars": 55,
"preview": "start pnunit-agent agent.conf\npnunit-launcher test.conf"
},
{
"path": "packages/NUnit.2.5.10.11092/tools/test.conf",
"chars": 778,
"preview": "<TestGroup>\n <ParallelTests>\n\n <ParallelTest>\n <Name>Testing</Name>\n <Tests>..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/net20/Newtonsoft.Json.xml",
"chars": 417353,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/net35/Newtonsoft.Json.xml",
"chars": 367561,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/net40/Newtonsoft.Json.xml",
"chars": 377190,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/sl3-wp/Newtonsoft.Json.xml",
"chars": 343311,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/sl4/Newtonsoft.Json.xml",
"chars": 345080,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/Newtonsoft.Json.4.0.8/lib/sl4-windowsphone71/Newtonsoft.Json.xml",
"chars": 343311,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Newtonsoft.Json</name>\n </assembly>\n <members>\n <m..."
},
{
"path": "packages/repositories.config",
"chars": 167,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<repositories>\n <repository path=\"..\\Tests\\packages.config\" />\n <repository pa..."
}
]
About this extraction
This page contains the full source code of the adrianaisemberg/CLAP GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 129 files (4.7 MB), approximately 1.2M tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.