/////////////////////////////////////////////////////////////////////// public static bool SetPresent( OptionDictionary options, string name, bool present, int index, Variant value ) { if (options != null) { if (name != null) { IOption option; if (options.TryGetValue(name, out option)) { if (option != null) { option.SetPresent(options, present, index, value); return(true); } } } } return(false); }
/////////////////////////////////////////////////////////////////////// #region Option Lookup Methods private static bool TryResolveSimple( OptionDictionary options, string name, bool verbose, ref IOption option, ref Result error ) { if (options == null) { error = "invalid options"; return(false); } if (name == null) { error = "invalid option name"; return(false); } if (!options.TryGetValue(name, out option)) { error = BadOption(verbose ? options : null, name); return(false); } if (option == null) { error = String.Format("invalid option \"{0}\"", name); return(false); } return(true); }
/////////////////////////////////////////////////////////////////////// public static bool Has( OptionDictionary options, string name ) { IOption option = null; return(Has(options, name, ref option)); }
/////////////////////////////////////////////////////////////////////// public static bool IsPresent( OptionDictionary options, string name, bool noCase ) { Variant value = null; return(IsPresent(options, name, noCase, ref value)); }
/////////////////////////////////////////////////////////////////////// public static bool IsPresent( OptionDictionary options, string name, bool noCase, ref Variant value, ref int index ) { return(IsPresent( options, name, noCase, true, ref value, ref index)); }
/////////////////////////////////////////////////////////////////////// public static bool Has( OptionDictionary options, string name, ref IOption option ) { Result error = null; return(TryResolveSimple( options, name, false, ref option, ref error)); }
/////////////////////////////////////////////////////////////////////// public static OptionDictionary FromString( Interpreter interpreter, string text, AppDomain appDomain, bool allowInteger, bool strict, bool verbose, bool noCase, CultureInfo cultureInfo, ref Result error ) { StringList list = null; if (Parser.SplitList( interpreter, text, 0, Length.Invalid, true, ref list, ref error) == ReturnCode.Ok) { OptionDictionary options = new OptionDictionary(); foreach (string element in list) { IOption option = Option.FromString( interpreter, element, appDomain, allowInteger, strict, verbose, noCase, cultureInfo, ref error); if (option == null) { return(null); } if (options.Has(option)) { error = String.Format( "duplicate option name {0}", FormatOps.WrapOrNull(option.Name)); return(null); } options.Add(option); } return(options); } return(null); }
/////////////////////////////////////////////////////////////////////// public static bool CanBePresent( OptionDictionary options, string name, ref Result error ) { IOption option = null; if (!TryResolveSimple(options, name, true, ref option, ref error)) { return(false); } return(option.CanBePresent(options, ref error)); }
/////////////////////////////////////////////////////////////////////// public static Result BadOption( OptionDictionary options, string name ) { if (options == null) { return(String.Format( "bad option \"{0}\"", name)); // FIXME: Fallback here? } return(String.Format( "bad option \"{0}\": must be {1}", name, ToEnglish(new StringSortedList(options.Keys)))); }
/////////////////////////////////////////////////////////////////////// public static Result AmbiguousOption( OptionDictionary options, /* NOT REALLY USED */ string name, StringList list ) { if ((options == null) || (list == null)) { return(String.Format( "ambiguous option \"{0}\"", name)); // FIXME: Fallback here? } return(String.Format( "ambiguous option \"{0}\": must be {1}", name, // ToEnglish(new StringSortedList(options.Keys))); ToEnglish(new StringSortedList(list)))); }
/////////////////////////////////////////////////////////////////////// public static Result ListOptions( OptionDictionary options, bool safe ) { if (options == null) { return("there are no available options"); } IDictionary <string, string> dictionary; if (safe) { dictionary = new StringSortedList(); foreach (KeyValuePair <string, IOption> pair in options) { IOption option = pair.Value; if ((option == null) || option.IsUnsafe(options)) { continue; } string name = pair.Key; if (name == null) { continue; } dictionary.Add(name, null); } } else { dictionary = new StringSortedList(options.Keys); } return(String.Format( "available options are {0}", ToEnglish(dictionary))); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode ToArgumentList( OptionDictionary options, ref ArgumentList arguments, ref Result error ) { if (options != null) { if (options.Count > 0) { if (arguments == null) { arguments = new ArgumentList(); } IOption endOption = null; foreach (KeyValuePair <string, IOption> pair in options) { IOption option = pair.Value; if (option == null) { continue; } if (option.IsIgnored(options)) { continue; } // // TODO: Is this a good idea (i.e. simply ignoring // the list-of-options flag instead of raising // an error)? // if (option.HasFlags(OptionFlags.ListOfOptions, true)) { continue; } if (!option.HasFlags(OptionFlags.EndOfOptions, true)) { Variant value = null; if (!option.IsPresent(options, ref value)) { continue; } if (!option.CanBePresent(options, ref error)) { return(ReturnCode.Error); } arguments.Add(Argument.InternalCreate(option.Name)); if (option.MustHaveValue(options)) { arguments.Add(Argument.InternalCreate(value)); } } else { // // NOTE: This option must be processed last; however, // we still need to keep track of it now until // that time. // endOption = option; } } if ((endOption != null) && !endOption.IsIgnored(options)) { Variant value = null; if (endOption.IsPresent(options, ref value)) { if (!endOption.CanBePresent(options, ref error)) { return(ReturnCode.Error); } arguments.Add(Argument.InternalCreate(endOption.Name)); if (endOption.MustHaveValue(options)) { arguments.Add(Argument.InternalCreate(value)); } } } } return(ReturnCode.Ok); } else { error = "invalid options"; } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode TryResolve( OptionDictionary options, string name, bool strict, bool noCase, ref IOption option, ref Result error ) { if (options != null) { if (name != null) { string exactName = null; StringList list = new StringList(); foreach (KeyValuePair <string, IOption> pair in options) { string key = pair.Key; IOption value = pair.Value; bool match; if (noCase || ((value != null) && value.IsNoCase(options))) { match = (String.Compare(key, 0, name, 0, name.Length, StringOps.SystemNoCaseStringComparisonType) == 0); } else { match = (String.Compare(key, 0, name, 0, name.Length, StringOps.SystemStringComparisonType) == 0); } if (match) { // // NOTE: Was the key valid (this should always succeed). // if (key != null) { // // NOTE: It was a match; however, was it an exact match? // if (key.Length == name.Length) { // // NOTE: Preserve match, it may differ in case. // exactName = key; } // // NOTE: Was it an exact match or did we match at least one // character in a partial match? // if ((key.Length == name.Length) || (name.Length > 0)) { // // NOTE: Store the exact or partial match in the results // dictionary. // list.Add(key); } } } } // // NOTE: If there was an exact match, just use it. // if (exactName != null) { // // NOTE: Normal case, an exact option match was found. // option = options[exactName]; return(ReturnCode.Ok); } else if (list.Count == 1) { // // NOTE: Normal case, exactly one option partially matched. // option = options[list[0]]; return(ReturnCode.Ok); } else if (list.Count > 1) { // // NOTE: They specified an ambiguous option. // error = AmbiguousOption(options, name, list); } else if (strict) { // // NOTE: They specified a non-existent option. // error = BadOption(options, name); } else { // // NOTE: Non-strict mode, leave the original option value // unchanged and let the caller deal with it. // return(ReturnCode.Ok); } } else { error = "invalid option name"; } } else { error = "invalid options"; } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Private private static bool IsPresent( OptionDictionary options, string name, bool noCase, bool strict, ref Variant value, ref int index ) { if (options != null) { if (name != null) { if (noCase) { // // HACK: Perform a linear search of the options. We // should not need to do this since the options // are in a dictionary; however, we want to // preserve the "case-sensitive" semantics unless // otherwise requested by the caller. // bool found = false; foreach (KeyValuePair <string, IOption> pair in options) { if (String.Compare(pair.Key, 0, name, 0, name.Length, StringOps.SystemNoCaseStringComparisonType) == 0) { found = true; IOption option = pair.Value; if ((option != null) && option.IsPresent(options, ref value)) { index = option.Index; return(true); } } } if (strict && !found) { // // NOTE: This should not really happen, issue a // debug trace. // TraceOps.DebugTrace(String.Format( "IsPresent: {0}", BadOption(options, name)), typeof(OptionDictionary).Name, TracePriority.Command); } } else { IOption option; if (options.TryGetValue(name, out option)) { if ((option != null) && option.IsPresent(options, ref value)) { index = option.Index; return(true); } } else if (strict) { // // NOTE: This should not really happen, issue a // debug trace. // TraceOps.DebugTrace(String.Format( "IsPresent: {0}", BadOption(options, name)), typeof(OptionDictionary).Name, TracePriority.Command); } } } } return(false); }