示例#1
0
        /// <summary>
        /// Tries to parse a string array of arguments, checking compliance with the rules formulated by a corresponding ProgramSettings object.
        /// </summary>
        /// <param name="args">A string array of arguments.</param>
        /// <param name="settings">Corresponding ProgramSettings object which specifies rules to which the parsed arguments must conform.</param>
        /// <param name="message">String to which an error message is assigned if any rules are found to be violated in the process of parsing. Otherwise, becomes an empty string.</param>
        /// <param name="result">ParseResult object to which the results of parsing are assigned if all rules are met. Otherwise, NULL.</param>
        /// <returns>Returns a ParseResult object, which is a compact representation of information obtained by parsing.</returns>
        internal static bool tryParse(string[] args, ProgramSettings settings, out string message, out ParseResult result)
        {
            result = new ParseResult();
            if (args.Length == 0)
            {
                message = Properties.Resources.Parser_tryParse_NoArguments;
                return(false);
            }

            int argsIterator = 0;

            if (args[0] == settings.programName)
            {
                ++argsIterator;
            }

            while (argsIterator < args.Length)
            {
                if (tryParsePlainArgs(ref args, argsIterator, ref result))
                {
                    break;
                }

                if (tryParseOptions(ref args, argsIterator, ref result, ref settings, out message))
                {
                    ++argsIterator;
                }
                else
                {
                    return(false);
                }
            }

            if (!mandatoryOptionsParsed(ref result, ref settings, out message))
            {
                return(false);
            }

            if (!dependenciesMet(ref result, ref settings, out message))
            {
                return(false);
            }

            if (!noConflictsPresent(ref result, ref settings, out message))
            {
                return(false);
            }

            if (!plainArgumentsCountAdmissible(ref result, ref settings, out message))
            {
                return(false);
            }

            message = "";
            return(true);
        }
示例#2
0
        /// <summary>
        /// Examines a ParseResult object and determines whether the number of parsed plain arguments is admissible,
        /// with respect to minimum and maximum counts formulated by a corresponding ProgramSettings object.
        /// </summary>
        /// <param name="result">ParseResult object to be examined.</param>
        /// <param name="settings">Corresponding ProgramSettings object which specifies the minimum and maximum number of plain arguments to be parsed.</param>
        /// <param name="diagnosis">String to which an error message is assigned if plain arguments count is not admissible. Otherwise, becomes an empty string.</param>
        /// <returns>Returns a Boolean value: is plain arguments count admissible?</returns>
        internal static bool plainArgumentsCountAdmissible(ref ParseResult result, ref ProgramSettings settings, out string diagnosis)
        {
            int count = result.PlainArguments.Count;

            if (count < settings.minPlainArgs || count > settings.maxPlainArgs)
            {
                diagnosis = Properties.Resources.Parser_plainArgumentsCountAdmissible_illegalNumberArgs;
                return(false);
            }
            diagnosis = "";
            return(true);
        }
示例#3
0
 /// <summary>
 /// Examines a ParseResult object and determines whether all mandatory options were parsed, with respect to rules formulated
 /// by a corresponding ProgramSettings object.
 /// </summary>
 /// <param name="result">ParseResult object to be examined.</param>
 /// <param name="settings">Corresponding ProgramSettings object which specifies which options are mandatory.</param>
 /// <param name="diagnosis">String to which an error message is assigned if any mandatory options are missing. Otherwise, becomes an empty string.</param>
 /// <returns>Returns a Boolean value: were all mandatory options parsed?</returns>
 internal static bool mandatoryOptionsParsed(ref ParseResult result, ref ProgramSettings settings, out string diagnosis)
 {
     foreach (Option option in settings.MandatoryOptions)
     {
         string name = option.Names.AsEnumerable().ElementAt(0);
         if (!result.WasParsed(name))
         {
             diagnosis = String.Format(Properties.Resources.Parser_mandatoryOptionsParsed_mandatoryOptionMissing, name);
             return(false);
         }
     }
     diagnosis = "";
     return(true);
 }
示例#4
0
        /// <summary>
        /// Reads a TextReader stream (representing a command) and parses arguments according
        /// to rules defined a corresponding ProgramSettings object.
        /// </summary>
        /// <param name="reader">System.IO.TextReader Object.</param>
        /// <param name="settings">Corresponding ProgramSettings object.</param>
        /// <returns>Returns a ParseResult object, which is a compact representation of information obtained by parsing.</returns>
        /// <exception cref="System.ArgumentException">Thrown if settings are undefined.</exception>
        /// <exception cref="CommandLineParser.ParseException">Thrown if command is illegal.</exception>
        public static ParseResult Parse(System.IO.TextReader reader, ProgramSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentException(Properties.Resources.Parser_Parse_SettingsNull);
            }
            if (reader == null)
            {
                throw new ArgumentException(Properties.Resources.Parser_Parse_ReaderNull);
            }

            if (!tryParse(argumentsArray(reader.ReadLine()), settings, out string message, out ParseResult result))
            {
                throw new ParseException(message);
            }
            return(result);
        }
示例#5
0
        /// <summary>
        /// Parses given string representing a command according to rules defined in a corresponding ProgramSettings object.
        /// </summary>
        /// <param name="cmdLine">Single command string.</param>
        /// <param name="settings">Corresponding ProgramSettings object.</param>
        /// <returns>Returns a ParseResult object, which is a compact representation of information obtained by parsing.</returns>
        /// <exception cref="System.ArgumentException">Thrown if settings are undefined.</exception>
        /// <exception cref="CommandLineParser.ParseException">Thrown if command is illegal.</exception>
        public static ParseResult Parse(string cmdLine, ProgramSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentException(Properties.Resources.Parser_Parse_SettingsNull);
            }
            if (cmdLine == null)
            {
                throw new ArgumentException(Properties.Resources.Parser_Parse_CmdLineNull);
            }

            if (!tryParse(argumentsArray(cmdLine), settings, out string message, out ParseResult result))
            {
                throw new ParseException(message);
            }
            return(result);
        }
示例#6
0
 /// <summary>
 /// Examines a ParseResult object and determines whether all option dependencies were met, with respect to rules formulated by a
 /// corresponding ProgramSettings object.
 /// </summary>
 /// <param name="result">ParseResult object to be examined.</param>
 /// <param name="settings">Corresponding ProgramSettings object which specifies option dependencies.</param>
 /// <param name="diagnosis">String to which an error message is assigned if any dependencies are unmet. Otherwise, becomes an empty string.</param>
 /// <returns>Returns a Boolean value: were all dependencies met?</returns>
 internal static bool dependenciesMet(ref ParseResult result, ref ProgramSettings settings, out string diagnosis)
 {
     foreach (KeyValuePair <Option, Option> entry in settings.OptionDependencies)
     {
         string dependentName = entry.Key.Names.AsEnumerable().ElementAt(0);
         if (result.WasParsed(dependentName))
         {
             string independentName = entry.Value.Names.AsEnumerable().ElementAt(0);
             if (!result.WasParsed(independentName))
             {
                 diagnosis = String.Format(Properties.Resources.Parser_dependenciesMet_dependencyUnmet, dependentName, independentName);
                 return(false);
             }
         }
     }
     diagnosis = "";
     return(true);
 }
示例#7
0
        /// <summary>
        /// Provided a reference to a Regex object for matching an argument string (possibly with parameter value), an option name string,
        /// a parameter value string, reference to a string array of arguments, an iterator (index), a reference to a ParseResult
        /// object and a reference to a corresponding ProgramSettings object, tries to parse a single option, with a possible parameter value.
        /// If successful, adds the option to the given ParseResult object using its addOption method.
        /// </summary>
        /// <param name="parameterRegex">Regex for matching a parameter value string.</param>
        /// <param name="optionName">Name of the option which should be parsed.</param>
        /// <param name="parameterString">Relevant parameter string value.</param>
        /// <param name="args">String array of arguments.</param>
        /// <param name="argsIterator">Index of element in the arguments array which is being evaluated.</param>
        /// <param name="result">ParseResult object. If option is legal, it is added, possibly with a corresponding parameter value, to the result via its addOption method.</param>
        /// <param name="settings">Corresponding ProgramSettings object, used for checking whether the parsed option and its potential parameter value are legal.</param>
        /// <param name="message">String to which a potential error message is assigned. Otherwise, becomes an empty string.</param>
        /// <returns>Returns a Boolean value: was the option (and, potentially, its parameter value) parsed successfully?</returns>
        internal static bool tryParseSingleOption(ref Regex parameterRegex, string optionName, string parameterString, ref string[] args, int argsIterator, ref ParseResult result, ref ProgramSettings settings, out string message)
        {
            Option option;
            object parameterValue = null;

            if (!settings.OptionsDictionary.TryGetValue(optionName, out option)) // get option name
            {                                                                    // if option name not recognised, error
                message = String.Format(Properties.Resources.Parser_tryParseSingleOption_InvalidOptionName, optionName);
                return(false);
            }

            if (parameterString == "" && option.Parameter != null)
            {     // if no parameter value was provided yet and option accepts parameter
                if ((argsIterator + 1) < args.Length)
                { // look for separate parameter value in the following position
                    var parameterMatch = parameterRegex.Match(args[argsIterator + 1]);
                    if (parameterMatch.Success)
                    {                                                                        // if separate parameter value found
                        parameterString = parameterMatch.Groups["parameterString"].ToString();
                        if (!option.Parameter.TryParse(parameterString, out parameterValue)) // get parameter value
                        {                                                                    // if it is invalid, error
                            message = String.Format(Properties.Resources.Parser_tryParseSingleOption_InvalidParameterValue, optionName);
                            return(false);
                        }
                    } // otherwise OK
                    else
                    { // else if value not found in the following position
                        if (option.Parameter.IsMandatory)
                        { // if it is mandatory, error
                            message = String.Format(Properties.Resources.Parser_tryParseSingleOption_NoParameterValue, optionName);
                            return(false);
                        }
                        parameterValue = null;
                    } // otherwise OK
                }
            }
            else
            {     // else if parameter value was provided, OR was not provided BUT option does not accept parameter...
                if (parameterString != "" && option.Parameter == null)
                { // if option does not accept parameter and parameter is provided, error
                    message = String.Format(Properties.Resources.Parser_tryParseSingleOption_TooManyParameterValue, optionName);
                    return(false);
                }
                // else
                if (parameterString != "")
                {
                    if (!option.Parameter.TryParse(parameterString, out parameterValue)) // get parameter value
                    {                                                                    // if parameter value is invalid, error
                        message = String.Format(Properties.Resources.Parser_tryParseSingleOption_InvalidParameterValue, optionName);
                        return(false);
                    }
                }
                else
                { // otherwise OK
                    parameterValue = null;
                }
            }
            ParsedOption parsedOption = new ParsedOption(option.Names, parameterValue);

            result.addOption(parsedOption);
            message = "";
            return(true);
        }
示例#8
0
        /// <summary>
        /// Provided a reference to a Match object, which is resulted from matching an argument against a grouped option regex,
        /// a reference to a ParseResult object and a reference to the corresponding ProgramSettings object, tries to parse a
        /// group of options, except for the last option. Furthermore, the name of the last option and its string parameter value
        /// (if it is provided as part of the same argument) are assigned to out-parameters of the method. (The method
        /// tryParseSingleOption is to be then used for the last option, since that method handles the possibility of a
        /// parameter value provided in a separate argument.)
        /// </summary>
        /// <param name="groupedOptionsMatch">A regex Match object generated by matching an argument string against a Regex object for grouped options.</param>
        /// <param name="result">ParseResult object. If legal options are detected, they are added to the object via its addOption method.</param>
        /// <param name="settings">Corresponding ProgramSettings object, used for checking if detected options exist.</param>
        /// <param name="message">String to which a potential error message is assigned. Otherwise, becomes an empty string.</param>
        /// <param name="lastOptionName">String to which name of the last option within the evaluated group of options is assigned. Otherwise if parsing fails, becomes an empty string.</param>
        /// <param name="parameterString">String to which string parameter value of the last option is assigned. Otherwise if parsing fails, becomes an empty string.</param>
        /// <returns>Returns a Boolean value: were grouped options parsed successfully?</returns>
        internal static bool tryParseGroupedOptions(ref Match groupedOptionsMatch, ref ParseResult result, ref ProgramSettings settings, out string message, out string lastOptionName, out string parameterString)
        {
            char[] groupedOptionNames = groupedOptionsMatch.Groups["optionName"].ToString().ToCharArray();

            for (int i = 0; i < (groupedOptionNames.Length - 1); ++i)
            { // try adding all options but the last (these do not have any parameters specified)
                Option groupedOption;
                string groupedOptionName = groupedOptionNames[i].ToString();
                if (!settings.OptionsDictionary.TryGetValue(groupedOptionName, out groupedOption)) // get option name
                {                                                                                  // if option name not recognised, error
                    message         = String.Format(Properties.Resources.Parser_tryParseGroupedOptions_InvalidOptionName, groupedOptionName);
                    lastOptionName  = "";
                    parameterString = "";
                    return(false);
                }
                else
                {     // if recognised
                    if (groupedOption.Parameter == null || !groupedOption.Parameter.IsMandatory)
                    { // if no parameter needed, add it to results
                        ParsedOption parsedOption = new ParsedOption(groupedOption.Names, value: null);
                        result.addOption(parsedOption);
                    }
                    else
                    { // otherwise if parameter needed, error
                        message         = String.Format(Properties.Resources.Parser_tryParseGroupedOptions_NoParameterValue, groupedOptionName);
                        lastOptionName  = "";
                        parameterString = "";
                        return(false);
                    }
                }
            }
            message         = "";
            lastOptionName  = groupedOptionNames[groupedOptionNames.Length - 1].ToString();
            parameterString = groupedOptionsMatch.Groups["parameterString"].ToString();
            return(true);
        }
示例#9
0
        /// <summary>
        /// Provided a reference to a string array of arguments, an iterator (index), a reference to a corresponding ParseResult object
        /// and a reference to the relevant ProgramSettings object, tries to parse all options and their parameter values within the
        /// sequence of arguments.
        /// </summary>
        /// <param name="args">String array of arguments.</param>
        /// <param name="argsIterator">Index of element in the arguments array which is being evaluated.</param>
        /// <param name="result">ParseResult object to which parsed options are to be added.</param>
        /// <param name="settings">Corresponding ProgramSettings object, specifying the rules by which the processes which check legality of parsed options are governed.</param>
        /// <param name="message">String to which a potential error message is assigned. Otherwise, becomes an empty string.</param>
        /// <returns>Returns a Boolean value: were the evaluated arguments parsed successfully as options and, potentially, their parameter values?</returns>
        internal static bool tryParseOptions(ref string[] args, int argsIterator, ref ParseResult result, ref ProgramSettings settings, out string message)
        {
            Regex parameterRegex = new Regex(@Properties.Resources.Parser_tryParseOptions_ParameterRegexString);

            if (parameterRegex.Match(args[argsIterator]).Success)
            { // if iterator at parameter, skip (this is handled with options directly)
                message = "";
                return(true);
            }

            Regex singleOptionRegex   = new Regex(@Properties.Resources.Parser_tryParseOptions_SingleOptionRegexString);
            Regex groupedOptionsRegex = new Regex(@Properties.Resources.Parser_tryParseOptions_GroupedOptionsRegexString);

            string optionName      = "";
            string parameterString = "";

            var groupedOptionsMatch = groupedOptionsRegex.Match(args[argsIterator]);
            var singleOptionMatch   = singleOptionRegex.Match(args[argsIterator]);

            if (groupedOptionsMatch.Success)
            { // if iterator at group of options
                if (!tryParseGroupedOptions(ref groupedOptionsMatch, ref result, ref settings, out message, out optionName, out parameterString))
                {
                    return(false);
                }
            }
            else if (singleOptionMatch.Success)
            {
                optionName      = singleOptionMatch.Groups["optionName"].ToString();
                parameterString = singleOptionMatch.Groups["parameterString"].ToString();
            }
            else
            {
                message = String.Format(Properties.Resources.Parser_tryParseOptions_InvalidOption, argsIterator, args[argsIterator]);
                return(false);
            }

            if (!tryParseSingleOption(ref parameterRegex, optionName, parameterString, ref args, argsIterator, ref result, ref settings, out message))
            {
                return(false);
            }

            message = "";
            return(true);
        }