// 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; } } } }