// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
using System;
using System.Globalization;
using System.IO;
using CommandLine.Infrastructure;
using CSharpx;
namespace CommandLine
{
///
/// Provides settings for . Once consumed cannot be reused.
///
public class ParserSettings : IDisposable
{
private const int DefaultMaximumLength = 80; // default console width
private bool disposed;
private bool caseSensitive;
private bool caseInsensitiveEnumValues;
private TextWriter helpWriter;
private bool ignoreUnknownArguments;
private bool autoHelp;
private bool autoVersion;
private CultureInfo parsingCulture;
private Maybe enableDashDash;
private int maximumDisplayWidth;
private Maybe allowMultiInstance;
private bool getoptMode;
private Maybe posixlyCorrect;
///
/// Initializes a new instance of the class.
///
public ParserSettings()
{
caseSensitive = true;
caseInsensitiveEnumValues = false;
autoHelp = true;
autoVersion = true;
parsingCulture = CultureInfo.InvariantCulture;
maximumDisplayWidth = GetWindowWidth();
getoptMode = false;
enableDashDash = Maybe.Nothing();
allowMultiInstance = Maybe.Nothing();
posixlyCorrect = Maybe.Nothing();
}
private int GetWindowWidth()
{
#if !NET40
if (Console.IsOutputRedirected) return DefaultMaximumLength;
#endif
var width = 1;
try
{
width = Console.WindowWidth;
if (width < 1)
{
width = DefaultMaximumLength;
}
}
catch (Exception e) when (e is IOException || e is PlatformNotSupportedException || e is ArgumentOutOfRangeException)
{
width = DefaultMaximumLength;
}
return width;
}
///
/// Finalizes an instance of the class.
///
~ParserSettings()
{
Dispose(false);
}
///
/// Gets or sets a value indicating whether perform case sensitive comparisons.
/// Note that case insensitivity only applies to parameters, not the values
/// assigned to them (for example, enum parsing).
///
public bool CaseSensitive
{
get { return caseSensitive; }
set { PopsicleSetter.Set(Consumed, ref caseSensitive, value); }
}
///
/// Gets or sets a value indicating whether perform case sensitive comparisons of values.
/// Note that case insensitivity only applies to values, not the parameters.
///
public bool CaseInsensitiveEnumValues
{
get { return caseInsensitiveEnumValues; }
set { PopsicleSetter.Set(Consumed, ref caseInsensitiveEnumValues, value); }
}
///
/// Gets or sets the culture used when parsing arguments to typed properties.
///
///
/// Default is invariant culture, .
///
public CultureInfo ParsingCulture
{
get { return parsingCulture; }
set
{
if (value == null) throw new ArgumentNullException("value");
PopsicleSetter.Set(Consumed, ref parsingCulture, value);
}
}
///
/// Gets or sets the used for help method output.
/// Setting this property to null, will disable help screen.
///
///
/// It is the caller's responsibility to dispose or close the .
///
public TextWriter HelpWriter
{
get { return helpWriter; }
set { PopsicleSetter.Set(Consumed, ref helpWriter, value); }
}
///
/// Gets or sets a value indicating whether the parser shall move on to the next argument and ignore the given argument if it
/// encounter an unknown arguments
///
///
/// true to allow parsing the arguments with different class options that do not have all the arguments.
///
///
/// This allows fragmented version class parsing, useful for project with add-on where add-ons also requires command line arguments but
/// when these are unknown by the main program at build time.
///
public bool IgnoreUnknownArguments
{
get { return ignoreUnknownArguments; }
set { PopsicleSetter.Set(Consumed, ref ignoreUnknownArguments, value); }
}
///
/// Gets or sets a value indicating whether implicit option or verb 'help' should be supported.
///
public bool AutoHelp
{
get { return autoHelp; }
set { PopsicleSetter.Set(Consumed, ref autoHelp, value); }
}
///
/// Gets or sets a value indicating whether implicit option or verb 'version' should be supported.
///
public bool AutoVersion
{
get { return autoVersion; }
set { PopsicleSetter.Set(Consumed, ref autoVersion, value); }
}
///
/// Gets or sets a value indicating whether enable double dash '--' syntax,
/// that forces parsing of all subsequent tokens as values.
/// If GetoptMode is true, this defaults to true, but can be turned off by explicitly specifying EnableDashDash = false.
///
public bool EnableDashDash
{
get => enableDashDash.MatchJust(out bool value) ? value : getoptMode;
set => PopsicleSetter.Set(Consumed, ref enableDashDash, Maybe.Just(value));
}
///
/// Gets or sets the maximum width of the display. This determines word wrap when displaying the text.
///
public int MaximumDisplayWidth
{
get { return maximumDisplayWidth; }
set { maximumDisplayWidth = value; }
}
///
/// Gets or sets a value indicating whether options are allowed to be specified multiple times.
/// If GetoptMode is true, this defaults to true, but can be turned off by explicitly specifying AllowMultiInstance = false.
///
public bool AllowMultiInstance
{
get => allowMultiInstance.MatchJust(out bool value) ? value : getoptMode;
set => PopsicleSetter.Set(Consumed, ref allowMultiInstance, Maybe.Just(value));
}
///
/// Whether strict getopt-like processing is applied to option values; if true, AllowMultiInstance and EnableDashDash will default to true as well.
///
public bool GetoptMode
{
get => getoptMode;
set => PopsicleSetter.Set(Consumed, ref getoptMode, value);
}
///
/// Whether getopt-like processing should follow the POSIX rules (the equivalent of using the "+" prefix in the C getopt() call).
/// If not explicitly set, will default to false unless the POSIXLY_CORRECT environment variable is set, in which case it will default to true.
///
public bool PosixlyCorrect
{
get => posixlyCorrect.MapValueOrDefault(val => val, () => Environment.GetEnvironmentVariable("POSIXLY_CORRECT").ToBooleanLoose());
set => PopsicleSetter.Set(Consumed, ref posixlyCorrect, Maybe.Just(value));
}
internal StringComparer NameComparer
{
get
{
return CaseSensitive
? StringComparer.Ordinal
: StringComparer.OrdinalIgnoreCase;
}
}
internal bool Consumed { get; set; }
///
/// Frees resources owned by the instance.
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposed)
{
return;
}
if (disposing)
{
// Do not dispose HelpWriter. It is the caller's responsibility.
disposed = true;
}
}
}
}